【问题标题】:PHPUnit test double throws PHPUnit_Framework_MockObject_BadMethodCallExceptionPHPUnit 测试双抛出 PHPUnit_Framework_MockObject_BadMethodCallException
【发布时间】:2015-04-11 19:59:48
【问题描述】:

我正在尝试创建一个模拟对象并在测试时在我的 Zend 框架应用程序中使用它:

public function testAskQuestionRouteWithLoggedIn()
{
    // get the mock auth object, and update the registry
    $auth = $this->getMockBuilder('QA_Auth')
        ->disableOriginalConstructor()
        ->getMock();

    // mock methods, and return values
    $auth->method('isAuthenticated')
        ->will( $this->returnValue( true ) );

    // update the registry
    $auth = Zend_Registry::set('Auth', $auth);

    // now preform the test as a logged in user
    $this->dispatch('/ask');
    $this->assertController('questions');
    $this->assertAction('new');

    // // // check the page contains a question form
    $this->assertQueryCount('form#questionForm', 1);
}

...但它抛出了 PHPUnit_Framework_MockObject_BadMethodCallException 异常,但并没有太多其他异常(例如原因)。如果我在我的应用程序中执行echo get_class($auth); exit;,我可以看到它属于Mock_QA_Auth_f4627b7b 类,所以至少它正在拾取模拟实例。但是当我调用 isAuthenticated 方法时,它会抛出该异常。我做错了什么?

这是我看到的错误消息:

$ ./vendor/bin/phpunit tests/application/controllers/QuestionsControllerTest.php 
PHPUnit 4.4.2 by Sebastian Bergmann.

Configuration read from /var/www/vhosts/qasystem/qasystem/tests/application/phpunit.xml

E

Time: 277 ms, Memory: 7.50Mb

There was 1 error:

1) QuestonsControllerTest::testAskQuestionRouteWithLoggedIn
PHPUnit_Framework_MockObject_BadMethodCallException: 

/var/www/vhosts/qasystem/qasystem/application/controllers/BaseController.php:331
/var/www/vhosts/qasystem/qasystem/application/controllers/BaseController.php:29
/var/www/vhosts/qasystem/qasystem/application/controllers/QuestionsController.php:14
/var/www/vhosts/qasystem/qasystem/vendor/zendframework/zendframework1/library/Zend/Controller/Action.php:133
/var/www/vhosts/qasystem/qasystem/vendor/zendframework/zendframework1/library/Zend/Controller/Dispatcher/Standard.php:281
/var/www/vhosts/qasystem/qasystem/vendor/zendframework/zendframework1/library/Zend/Controller/Front.php:954
/var/www/vhosts/qasystem/qasystem/vendor/zendframework/zendframework1/library/Zend/Application/Bootstrap/Bootstrap.php:105
/var/www/vhosts/qasystem/qasystem/vendor/zendframework/zendframework1/library/Zend/Application.php:382
/var/www/vhosts/qasystem/qasystem/tests/application/controllers/BaseControllerTestCase.php:67
/var/www/vhosts/qasystem/qasystem/tests/application/controllers/QuestionsControllerTest.php:26

【问题讨论】:

  • 请发布您遇到的错误...也许正在调用 isAuthenticated 以外的方法,但不存在。尝试在创建其模拟之前确保真正的 QA_class 已加载或可自动加载
  • 我已经用运行测试时收到的错误消息更新了我的问题。我还尝试简单地从测试中创建一个 $auth = new QA_Auth() 实例,并且可以确认正在加载该类,因此肯定是可见的。
  • 好的,有点奇怪,但我一直在对其他一些文件进行更改,现在这对我有用。也许这不是我的测试脚本的错误。不确定问题是什么,因为它似乎并没有泄露太多。无论如何,感谢您的帮助,如果我弄清楚问题所在,我会回复。我想了解自己。
  • 遇到了这个错误,就我而言,它恰好是我试图模拟 github.com/sebastianbergmann/phpunit-mock-objects/issues/… 的公共静态方法的情况

标签: php zend-framework phpunit


【解决方案1】:

QA_Auth::isAuthenticated() 是静态方法,不能模拟静态方法。

限制:final、private 和 static 方法

请注意,final、private 和 static 方法不能被存根或模拟。它们被 PHPUnit 的测试双重功能忽略并保留其原始行为。

——Test Doubles

手册说测试替身“保留其原始行为”,但静态方法并非如此。有一个open issue about it。另见PHPUnit Mock Objects and Static Methods

【讨论】:

    猜你喜欢
    • 2018-02-21
    • 2018-03-31
    • 2020-12-21
    • 1970-01-01
    • 1970-01-01
    • 2019-11-10
    • 2012-03-10
    • 2021-06-20
    • 1970-01-01
    相关资源
    最近更新 更多