symfony - 如何用phpunit模拟依赖注入(inject)?

标签 symfony mocking phpunit

我希望在这个类中测试方法:

class EmailerService
{
    protected $mailer;
    protected $router;
    protected $em;
    protected $emailMan;
    protected $emailReminderMan;
    protected $secret;

    /**
     * Construct
     *
     * @param \Swift_Mailer                                             $mailer
     * @param \Symfony\Bundle\FrameworkBundle\Routing\Router            $router
     * @param \Doctrine\ORM\EntityManager                               $em
     * @param EmailManager                                              $emailMan
     * @param EmailReminderManager                                      $emailReminderMan
     * @param                                                           $secret
     */
    public function __construct(Swift_Mailer $mailer, Router $router, EntityManager $em, EmailManager $emailMan, EmailReminderManager $emailReminderMan, $secret)
    {
        $this->mailer = $mailer;
        $this->router = $router;
        $this->em = $em;
        $this->emailMan = $emailMan;
        $this->emailReminderMan = $emailReminderMan;
        $this->secret = $secret;
    }

我的测试目前看起来像这样:
class EmailerServiceTest extends \PHPUnit_Framework_TestCase
{
    protected $emailer;

    public function setUp()
    {
        $mailer = $this->getMockBuilder('Swift_Mailer')
            ->disableOriginalConstructor()
            ->getMock();

        $router = $this->getMockBuilder('Router')
            ->disableOriginalConstructor()
            ->getMock();

        $em = $this->getMockBuilder('EntityManager')
            ->disableOriginalConstructor()
            ->getMock();

        $emailMan = $this->getMockBuilder('EmailManager')
            ->disableOriginalConstructor()
            ->getMock();

        $emailReminderMan = $this->getMockBuilder('EmailReminderManager')
            ->disableOriginalConstructor()
            ->getMock();

        $secret = '123';

        $this->emailer = new EmailerService($mailer, $router, $em, $emailMan, $emailReminderMan, $secret);
    }

但我得到了错误:

1) T\CBundle\Tests\Service\EmailerServiceTest::testGetVariablesForModule Argument 2 passed to T\CBundle\Service\EmailerService::__construct() must be an instance of Symfony\Bundle\FrameworkBundle\Routing\Router, instance of Mock_Router_3e61717e given, called in ...



也有点困惑为什么它会触发路由器,而不是首先触发 Swift_Mailer

最佳答案

你必须使用真正的类名,否则 PHPunit 将创建一个名为 Router 的类。 (注意:这不是预期的 Symfony\Component\Routing\Router ):

     // don't need it here, Swift_Mailer is in the global scope
    $mailer = $this->getMockBuilder('Swift_Mailer')
        ->disableOriginalConstructor()
        ->getMock();

    $router = $this->getMockBuilder('Symfony\Bundle\FrameworkBundle\Routing\Router')
        ->disableOriginalConstructor()
        ->getMock();

    $em = $this->getMockBuilder('Doctrine\ORM\EntityManager')
        ->disableOriginalConstructor()
        ->getMock();

    $emailMan = $this->getMockBuilder('Full\Namespace\To\EmailManager')
        ->disableOriginalConstructor()
        ->getMock();

    $emailReminderMan = $this->getMockBuilder('Full\Namespace\To\EmailReminderManager')
        ->disableOriginalConstructor()
        ->getMock();

关于symfony - 如何用phpunit模拟依赖注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21476638/

相关文章:

java - EasyMock 在没有匹配器的方法调用记录中抛出匹配器错误?

c# - 使用 Nsubstitute 进行模拟但出现错误

mysql - 更快的 Laravel 迁移,用于测试具有大量表的项目

unit-testing - 调用模型的 Laravel 4 测试 Controller

javascript - AJAX 调用 [object%20Object] 而不是 URL (Symfony)

php - 测试中的 Symfony2 UrlGenerator

php - 如何使用 PHPUnit 重置模拟对象

php - Magento/PHPUnit - 强制异常

php - 交响乐 2 : Global Database Query

php - Symfony2 中的多线程