Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHPUnit test double throws PHPUnit_Framework_MockObject_BadMethodCallException

I'm trying to create a mock object and use that within my Zend framework application when testing:

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);
}

...but it's throwing a PHPUnit_Framework_MockObject_BadMethodCallException exception, but not really much else (e.g. reason why). If I do a echo get_class($auth); exit; from within my application I can see that it is of Mock_QA_Auth_f4627b7b class, so at least it's picking up the mock instance. But when I call the isAuthenticated method, it throws that exception. What am I doing wrong?

Here is the error message I'm seeing:

$ ./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
like image 954
Martyn Avatar asked Feb 11 '15 12:02

Martyn


1 Answers

QA_Auth::isAuthenticated() is a static method, static methods can't be mocked.

Limitation: final, private, and static methods

Please note that final, private and static methods cannot be stubbed or mocked. They are ignored by PHPUnit's test double functionality and retain their original behaviour.

— Test Doubles

The manual says that test doubles "retain their original behaviour", but that isn't true for static methods. There is an open issue about it. Also see PHPUnit Mock Objects and Static Methods.

like image 152
Gerard Roche Avatar answered Oct 17 '22 06:10

Gerard Roche