2014-01-31 97 views
3

我想測試這一類方法:如何用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

+0

是什麼'$ router'進入第二個代碼片段? – DonCallisto

+0

@DonCallisto正確的文件在頂部導入/使用;路由器具體是Symfony \ Bundle \ FrameworkBundle \ Routing \ Router – Tjorriemorrie

+0

'新的EmailerService($郵件程序,$路由器,....)'你能告訴我們'$ router'的聲明嗎?此外,我可否知道'EmailerService'是否已註冊爲服務或僅是您使用的命名約定? – DonCallisto

回答

3

你有用真實的類名,否則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();