3

I am not sure if I am doing something wrong or it is a bug with PHPUnit and mock objects. Basically I am trying to test if $Model->doSomething() is called when $Model->start() is triggered.

I am using Ubuntu in a VirtualBox, and phpunit 1.1.1 installed via pear.

The full code is below. Any help would be appreciated, it's driving me crazy.

<?php
require_once 'PHPUnit/Autoload.php';

class Model
{
    function doSomething( ) {
        echo 'Hello World';
    }

    function doNothing( ) { }

    function start( ) {
        $this->doNothing();
        $this->doSomething();
    }
}

class ModelTest extends PHPUnit_Framework_TestCase
{
    function testDoSomething( )
    {
        $Model = $this->getMock('Model');
        $Model->expects($this->once())->method('start'); # This works
        $Model->expects($this->once())->method('doSomething'); # This does not work
        $Model->start();
    }
}
?>

The output from PHPUnit:

There was 1 failure:

1) ModelTest::testDoSomething
Expectation failed for method name is equal to <string:doSomething> when invoked 1 time(s).
Method was expected to be called 1 times, actually called 0 times.


FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
4
  • I got it working, but i have had to pass the methods as an array. code $Model = $this->getMock('Model',array('doSomething','doNothing')); #$Model->expects($this->once())->method('start'); # This works Commented Aug 26, 2012 at 17:33
  • Does anybody know why you have to specify the methods. Is this a configuration issue. Many examples of using mocks does not state you have to specify methods. Commented Aug 26, 2012 at 20:14
  • Did you really mean phpUnit 1.1.1? Latest is 3.7, and the earliest you're likely to encounter in a supported linux distro is phpUnit 3.4 or so. Commented Aug 27, 2012 at 8:02
  • Sorry my bad, not sure where I got the 1.1.1 from, i am using the version 3.6.12. Thanks to everybody for your help. Commented Aug 27, 2012 at 17:44

2 Answers 2

3

As you found, you need to tell PHPUnit which methods to mock. Also, I would avoid creating expectations for methods that you are calling directly from the test. I would write the above test like this:

function testDoSomething( )
{
    $Model = $this->getMock('Model', array('doSomething');
    $Model->expects($this->once())->method('doSomething');
    $Model->start();
}
Sign up to request clarification or add additional context in comments.

Comments

0

Just to expand on why David Harkness's answer works, if you do not specify the $methods parameter to getMock then all functions in the class are mocked. Incidentally, you can confirm this with:

class ModelTest extends PHPUnit_Framework_TestCase
{
    function testDoSomething( )
    {
        $obj = $this->getMock('Model');
        echo new ReflectionClass(get_class($obj));
        ...
    }
}

So, why does it fail? Because your start() function has been mocked too! I.e. the function body you have given has been replaced, and so your $this->doSomething(); line never gets run.

Hence, when there are any functions in your class that you need to be preserved, you'll have to explicitly give the list of all other functions.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.