首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >调用模拟函数,但期望($this->once())失败

调用模拟函数,但期望($this->once())失败
EN

Stack Overflow用户
提问于 2016-11-15 22:19:50
回答 1查看 1.9K关注 0票数 1

我正在测试一个Symfony命令来发送提醒短信。为此,我为我的文本消息接口创建了一个服务,并且正在模拟容器以及文本消息传递服务:

测试下的函数

代码语言:javascript
复制
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);

}

测试

代码语言:javascript
复制
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' )
            ;

}

更新测试,全部在一个文件

代码语言:javascript
复制
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测试呼叫**

代码语言:javascript
复制
/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

当我调试测试时,我可以看到$textMessage是一个模拟。

然而,在断言()中的测试结束时,我得到了一个错误:

代码语言:javascript
复制
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",但是重命名函数没有帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-11-17 16:13:06

这里有一个小小的虚幻案例来澄清我在评论中提到的几点。此外,它还有一个失败的测试,当在对方法执行完全统一的方法更新测试之后设置期望时(这看起来是一个完整的方法更新测试的情况)。

代码语言:javascript
复制
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是如何工作的。真对不起。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40620757

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档