2016-11-15 60 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是如何工作的,对不起,