在 PHPUnit 测试中使用 Symfony Router 组件生成 URL

Generating URL with Symfony Router component in PHPUnit test

我正在尝试在 PHPUnit 中为一个简单的方法编写一个测试,该方法 returns 一个 URL 基于子域的 Symfony 路由。我不确定我的测试是否可以正确访问 Symfony Router 组件,这就是它失败的原因,但我现在似乎无法让它通过。

这是我遇到的错误:

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

这是我的测试和数据提供者:

/**
 * @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',
        ],
    ];
}

这是我的 getRouterMock 方法:

/**
 * @return \Symfony\Bundle\FrameworkBundle\Routing\Router
 */
protected function getRouterMock()
{
    return $this->getMockBuilder('\Symfony\Bundle\FrameworkBundle\Routing\Router')
        ->disableOriginalConstructor()
        ->setMethods(['generate', 'supports', 'exists'])
        ->getMockForAbstractClass();
}

这是我正在测试的方法:

/**
 * @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);
}

但是你没有正确访问 Symfony 路由器,你在嘲笑它。 在这个模拟中,你没有定义 return 在 generate() 方法调用上的内容,所以难怪它是 returning null.

你缺少的部分是

/**
 * @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;
}