6

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
Martyn
  • 6,031
  • 12
  • 55
  • 121
  • Please post the error you're getting... Maybe a method other than isAuthenticated is being called, but does not exist. Try making sure the real QA_class is loaded or autoloadable before creating its mock – gontrollez Feb 11 '15 at 15:39
  • I've updated my question with the error message I receive when running the test. I've also tried simply to create a `$auth = new QA_Auth()` instance from the test and can confirm that the class is being loaded that was, so is certainly visible. – Martyn Feb 12 '15 at 04:27
  • Ok, bit strange but I'd been making changes to some other files and now this is working for me. Perhaps it wasn't an error with my test scripts. Not sure what the problem was as it didn't seem to give much away. Thanks for your help anyway, if I figure out what the problem was I'll post back. I'd like to know myself anwyay. – Martyn Feb 12 '15 at 09:32
  • 3
    Ran into this error and for my case it happened to be the case of a public-static-method I tried to mock https://github.com/sebastianbergmann/phpunit-mock-objects/issues/169#issuecomment-43485962 – Jaak Kütt Aug 14 '15 at 06:42

1 Answers1

5

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.

Gerard Roche
  • 6,162
  • 4
  • 43
  • 69