如何使用phpunit进行依赖注入的模拟?

12

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

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 T\CBundle\Service\EmailerService::__construct() 的第二个参数必须是 Symfony\Bundle\FrameworkBundle\Routing\Router 的实例, 实际给出的是 Mock_Router_3e61717e 的实例,调用位置为...

我也有点困惑为什么它会触发 Router 错误,而不是先触发 Swift_Mailer 错误。


$router 在第二个代码片段中是什么? - DonCallisto
@DonCallisto 正确的文件已在顶部导入/使用;具体来说,Router 是 Symfony\Bundle\FrameworkBundle\Routing\Router。 - Tjorriemorrie
new EmailerService($mailer, $router, .... ) 你能展示一下 $router 的声明吗?此外,我想知道 EmailerService 是作为服务注册的还是只是你使用的命名约定? - DonCallisto
尝试使用$this->getMockBuilder('Symfony\Bundle\Frameworkbundle\Routing\Router') - Touki
@Tjorriemorrie:抱歉,我没有注意到你实例化它的代码... - DonCallisto
@Touki 谢谢,那就是答案了,它是字符串,所以我必须使用FQN。如果你回答的话,我会接受的。非常感谢。 - Tjorriemorrie
1个回答

14

您必须使用真正的类名,否则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();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接