2016-11-15 55 views
0

我正在測試Symfony命令發送提醒文本消息。爲此,我創建了一個服務,爲我的短信界面和我嘲諷容器以及該短信服務:

下測試

protected function textReminders() 
{ 
    $mailer = $this->getContainer()->get('mailer'); 
    $em = $this->getContainer()->get('doctrine')->getManager(); 


    if ($this->getContainer()->get('kernel')->getEnvironment() == 'dev'){ 
     $debug = true; 
    }else{ 
     $debug = false; 
    } 

    $textMessage = $this->getContainer()->get('text_messaging.interface'); 
    $textMessage->sendSMS($target, $content, $debug); 

} 

測試

private function getMockContainer() 
{ 
    $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\Container') 
         ->disableOriginalConstructor() 
         ->setMethods(array('get')) 
         ->getMock(); 

    return $container; 
} 

protected function setupMocks() 
{ 
    $mockText = $this->getMockBuilder('TextaHQ') 
        ->disableOriginalConstructor() 
        ->setMethods(array('sendSMS')) 
        ->getMock(); 
    $mockContainer = $this->getMockContainer(); 

    $container = self::$kernel->getContainer(); 
    $mockContainer->method('get') 
     ->withConsecutive(['mailer'], ['doctrine'], ['kernel'], ['text_messaging.interface']) 
     ->willReturnOnConsecutiveCalls(
      $this->returnValue($container->get('mailer')), 
      $this->returnValue($container->get('doctrine')), 
      $this->returnValue(self::$kernel), 
      $this->returnValue($mockText)) 
    ; 

    $this->setMyMock([ 
         'text' => $mockText, 
         'container' => $mockContainer 
        ]); 
} 

public function testExecute() 
{ 
    $this->setupMocks(); 
    self::bootKernel(); 
    $application = new Application(self::$kernel); 

    $application->add(new ActionRemindCommand()); 

    $command = $application->find('ahp:remind'); 
    $command->setContainer($this->getMyMock()['container']); 
    $commandTester = new CommandTester($command); 

    $commandTester->execute(array(
            'command' => $command->getName(), 
            'type' => 'text' 
           )); 
    $output = $commandTester->getDisplay(); 

    $this->assertions(); 
} 

protected function assertions() 
{ 
    $this->getMyMock()['text'] 
     ->expects($this->once()) 
      ->method('sendSMS') 
      ; 

} 
功能

已更新測試,全部在一個文件中

public function testExecute() 
{ 
    $insertSql = 'echo "' 
     . str_replace(
      array('"' ,'`' ), 
      array('\\"' ,'\\`'), 
      $this->getPrepSql()) 
     . '" | mysql ahp_example_com'; 
    exec($insertSql); 

    self::bootKernel(); 

    $mockText = $this->getMockBuilder('TextaHQ') 
        ->disableOriginalConstructor() 
        ->setMethods(array('sendSMS')) 
        ->getMock(); 
    $mockContainer = $this->getMockBuilder('Symfony\Component\DependencyInjection\Container') 
             ->disableOriginalConstructor() 
             ->setMethods(array('get')) 
             ->getMock(); 

    $container = self::$kernel->getContainer(); 
    $mockContainer->method('get') 
        ->withConsecutive(['mailer'], ['doctrine'], ['kernel'], ['text_messaging.interface']) 
        ->willReturnOnConsecutiveCalls(
         $this->returnValue($container->get('mailer')), 
         $this->returnValue($container->get('doctrine')), 
         $this->returnValue(self::$kernel), 
         $this->returnValue($mockText)) 
    ; 


    $application = new Application(self::$kernel); 

    $application->add(new ActionRemindCommand()); 

    $mailer = self::$kernel->getContainer()->get('swiftmailer.mailer'); 
    $logger = new \Swift_Plugins_MessageLogger(); 
    $mailer->registerPlugin($logger); 
    $this->setMailCollector($logger); 

    $output = ''; 
    for($i=1;$i<=$this->getRunNoTimes();$i++) { 
     $command = $application->find('ahp:remind'); 
     $command->setContainer($mockContainer); 
     $commandTester = new CommandTester($command); 

     $commandTester->execute(array(
            'command' => $command->getName(), 
            'type' => 'text' 
           )); 
     $output .= $commandTester->getDisplay(); 
    } 

    $mockText 
     ->expects($this->once()) 
     ->method('sendSMS') 
    ; 
} 

** PHPStorm測試呼叫**

/usr/bin/php  /home/jochen/projects/ahp/trunk/vendor/phpunit/phpunit/phpunit --configuration /home/jochen/projects/ahp/trunk/app/phpunit.xml.dist AgriHealth\AhpBundle\Tests\Command\ActionRemindCommandVet7DaysBeforeTest /home/jochen/projects/ahp/trunk/src/AgriHealth/AhpBundle/Tests/Command/RemindText/ActionRemindCommandVet7DaysBeforeTest.php --teamcity 
Testing started at 10:25 AM ... 
PHPUnit 5.5.4 by Sebastian Bergmann and contributors. 


Expectation failed for method name is equal to <string:sendSMS> when invoked 1 time(s). 
Method was expected to be called 1 times, actually called 0 times. 



Time: 1.12 seconds, Memory: 18.00MB 


FAILURES! 
Tests: 1, Assertions: 1, Failures: 1. 

Process finished with exit code 1 

當我調試測試,我可以看到,$文字信息是一個模擬。

但是在斷言()在測試結束時,我得到一個錯誤:

Expectation failed for method name is equal to <string:sendsms> when invoked 1 time(s). 
Method was expected to be called 1 times, actually called 0 times. 

調試器顯示的嘲笑功能爲小寫:「sendsms」,但重命名功能沒有幫助。

+0

看起來像你的模擬配置超出了'testExecute'範圍。意味着你不能通過'$ this-> setMyMock()'存儲你的模擬,並在稍後用'$ this-> getMyMock()'提取它以斷言。PHPUnit將無法跟蹤調用更多細節:[Only mock objects產生在測試範圍內將由PHPUnit自動驗證。](https://phpunit.de/manual/current/en/test-doubles.html#test-doubles.mock-objects) – xmike

+0

我已經完成了它方式來集中創建模擬對象並測試一組測試的執行。只有輸入數據和每個測試的結果發生變化。這是不可能的。我必須反覆重複嗎? – jdog

+1

更精確:您可以創建模擬對象的實例並在'testMethod'之外對其進行一些常規配置,但所有的擴展必須在'testMethod'內部定義。這是因爲PHPUnit將這樣的期望綁定到這個'testMethod'(當調用'testMethod'時,所有期望都被註冊爲這種方法的預期)。 – xmike

回答

1

這裏是一個小illustartive案件,以澄清我在評論中提到的觀點。此外,它擁有時的期望所設置的情形失敗的測試進行實際工作中調用該方法後(這看起來是您的ALL-IN-一方法更新測試的情況。

class MyClass 
{ 
    public function someMethod(){ 

    } 
} 

class ExpectationsTest extends PHPUnit_Framework_TestCase 
{ 
    private $myClassMock; 

    public function setUp(){ 
     $this->myClassMock = $this->getMock('MyClass'); 
    } 

    public function testLocalMock(){ 
     $localMock = $this->getMock('MyClass'); 
     $localMock->expects($this->once()) 
        ->method('someMethod'); 
     $localMock->someMethod(); 
    } 

    public function testClassScopeMockInstance(){ 
     $this->myClassMock->expects($this->once()) 
          ->method('someMethod'); 
     $this->myClassMock->someMethod(); 
    } 

    public function testWillFailBecauseExpectationWasSetAfterCall(){ 
     $this->myClassMock->someMethod(); 
     $this->myClassMock->expects($this->once()) 
          ->method('someMethod'); 
    } 

    public function testCanUseHelperToCreateLocalMock(){ 
     $mock = $this->createMyClassMock(); 
     $mock->expects($this->once()) 
      ->method('someMethod'); 
     $mock->someMethod(); 
    } 

     private function createMyClassMock(){ 
      return $this->getMock('MyClass'); 
     } 

    public function testCanSetExpectationsInHelper(){ 
     $this->setExpecatationsOnTestCaseScopeMock(); 
     $this->myClassMock->someMethod(); 
    } 

     private function setExpecatationsOnTestCaseScopeMock(){ 
      $this->myClassMock->expects($this->once()) 
           ->method('someMethod'); 
     } 
} 

順便說一句,我認爲第一次我沒有足夠透徹地瞭解你的代碼,我想我可能錯過了你的setupMocksgetMyMock是如何工作的,對不起,

相關問題