Mock Objects in PHPUnit

While I am preparing the PHPUNIT_2_3 CVS branch for a release of PHPUnit 2.3.0 alongside PHP 5.1.0, I recently started working on support for Mock Objects in PHPUnit.

Suppose you have the following class Foo:

class Foo {
    public function bar() {
    }
}
?>
You can now write a test case that checks whether or not the bar() method gets called on an object of the Foo class:
require_once 'PHPUnit2/Framework/TestCase.php';

class FooTest extends PHPUnit2_Framework_TestCase {
    public function testBarGetsCalled() {
        $mock = $this->getMockObject('Foo');
        $mock->__expectAtLeastOnce('bar');
        $mock->bar();
    }
}
?>
The test above will succeed when the bar() method gets called at least once on the $mock object inside the scope of the testBarGetsCalled() method.

The getMockObject('Foo') call generates a class MockFoo (the Mock Object class for Foo) that extends from Foo and the signatures of all public methods are copied from Foo to MockFoo. In addition, a couple of MockObjects API methods are added to the MockFoo class:
  • __expectArguments($method, $arguments, $message = "")
  • __expectArgumentsAt($method, $arguments, $timing, $message = "")
  • __expectCallCount($method, $count, $message = "")
  • __expectMaximumCallCount($method, $count, $message = "")
  • __expectMinimumCallCount($method, $count, $message = "")
  • __expectNever($method, $message = "")
  • __expectOnce($method, $arguments = FALSE, $message = "")
  • __expectAtLeastOnce($method, $arguments = FALSE, $message = "")
  • __getCallCount($method)
  • __setReturn($method, $value, $arguments = FALSE)
  • __setReturnAt($method, $value, $timing, $arguments = FALSE)
These methods can be used to set up expectations and return values for the stubbed-out methods of the Mock Object.

The work on the Code Generator that generates the code for a Mock Object class is complete and I started to integrate the Mock Objects functionality into the PHPUnit framework.