Frage

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.
War es hilfreich?

Lösung

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

Andere Tipps

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top