【问题标题】:Mock mailer and set to container模拟邮件并设置为容器
【发布时间】:2015-04-15 17:03:11
【问题描述】:

我目前正在为 symfony2 中的忘记密码函数编写 PHPUnit 测试用例。

我想要做的是:

  • 模拟一个邮件类并将其设置在控制器容器中进行即时测试。

这是模拟:

private function getMockMailer($return)
{
    $mailer = $this->getMockBuilder('Swift_Mailer')
            ->disableOriginalConstructor()
            ->setMethods(array('send'))
            ->getMock();

    $mailer->expects($this->any())
        ->method('send')
        ->with($this->anything())
        ->will($this->returnValue($return));

    return $mailer;
}

转储模拟对象返回:“Mock_Swift_Mailer_02ed3dbc”,这是正确的。

但是当我在控制器中转储邮件程序类时,我得到“Swift_Mailer”,它不是模拟对象。

这是我在测试中设置邮件程序的方式:

    $container = static::$kernel->getContainer();
    $mailer = $this->getMockMailer(true);

    $container->set('mailer', $mailer);

    $controller = new LoginController();
    $controller->setContainer($container);

我使用相同的方法来模拟路由器和模板类,并且效果很好。 Mailer 是唯一一个给我这个问题的人。

感谢任何想法,谢谢。

【问题讨论】:

    标签: php unit-testing symfony


    【解决方案1】:

    您在应用程序架构的方法上肯定是错误的。 从容器中获取服务的方法很快,但是对于使用模拟进行单元测试来说,这是一种杀戮方式。

    错误:

    $container->set('mailer', $mailer);
    

    你应该改用依赖注入模式

    和你一样

    $controller->setContainer($container);
    

    你应该设置邮件的DI

    您可以在实际使用中使用https://github.com/schmittjoh/JMSDiExtraBundle/tree/master

    作为

    use JMS\DiExtraBundle\Annotation as DI;
    
    class Controller
    {
        /** @DI\Inject("mailer") */
        private $mailer; 
    
        public function setMailer($mailer)
        {
            $this->mailer = $mailer; 
        }
    

    但是你应该在你的单元测试中使用“setMailer”

    $controller->setMailer($this->getMockMailer(true));
    

    【讨论】:

    • 这是我最初的想法,使用 setter 和 getter,但我认为测试中的服务容器与控制器中使用的容器相同。显然不是 :) 感谢您的建议,我会使用这种方法。
    猜你喜欢
    • 1970-01-01
    • 2013-02-28
    • 2023-03-13
    • 2013-06-05
    • 2019-09-07
    • 2013-02-27
    • 2017-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多