Reputation: 17181
I am attempting to write a test in PHPUnit for a simple method which returns a URL based on a Symfony route for a subdomain. I'm not sure if my test has proper access to the Symfony Router component and that is why it is falling over, but I can't quite seem to get it to pass at the moment.
This is the error I am getting:
There was 1 error:
1) CRMPiccoBundle\Tests\Services\MailerHelperTest::testReturnsBillingURL with data set "crmpicco.co.uk" (CRMPiccoBundle\Entity\Course Object (...), 'https://www.crmpicco.co.uk/en/admin/billing') TypeError: Return value of CRMPiccoBundle\Services\MailerHelper::getBillingUrlForSubdomain() must be of the type string, null returned
This is my test and data provider:
/**
* @dataProvider dataProvider
*/
public function testReturnsBillingURL(Course $course, string $expectedUrl)
{
$mailerHelper = new MailerHelper($this->getRouterMock());
$this->assertEquals($expectedUrl, $mailerHelper->getBillingUrlForSubdomain($course, true));
}
public function dataProvider()
{
return [
'crmpicco.co.uk' => [
'site' => (new Course())
->setSubdomain('crmpicco'),
'expectedUrl' => 'https://www.crmpicco.co.uk/en/admin/billing',
],
];
}
This is my getRouterMock method:
/**
* @return \Symfony\Bundle\FrameworkBundle\Routing\Router
*/
protected function getRouterMock()
{
return $this->getMockBuilder('\Symfony\Bundle\FrameworkBundle\Routing\Router')
->disableOriginalConstructor()
->setMethods(['generate', 'supports', 'exists'])
->getMockForAbstractClass();
}
This is the method I am testing:
/**
* @param Course $course
* @param bool $absoluteUrl
*
* @return string
*/
public function getBillingUrlForSubdomain(Course $course, bool $absoluteUrl = true) : string
{
return $this->router->generate('crmpiccobundle_portal_billing', [
'subdomain' => $site->getSubdomain(),
], $absoluteUrl);
}
Upvotes: 0
Views: 2245
Reputation: 3051
But you don't get a proper access to a Symfony Router, you're mocking it.
And in this mock, you don't define what to return on generate()
method call, so no wonder it's returning null
.
Your missing piece is
/**
* @return \Symfony\Bundle\FrameworkBundle\Routing\Router
*/
protected function getRouterMock()
{
$mock = $this->getMockBuilder('\Symfony\Bundle\FrameworkBundle\Routing\Router')
->disableOriginalConstructor()
->setMethods(['generate', 'supports', 'exists'])
->getMockForAbstractClass();
$args = ['crmpiccobundle_portal_billing', [
'subdomain' => "crmpicco",
], true];
$mock->expects($this->any())
->method('generate')
->withArgs($args)
->will($this->returnValue('https://www.crmpicco.co.uk/en/admin/billing'));
return $mock;
}
Upvotes: 2