Function mocking with Patchwork 09

Where I explore the possibilities I have to use what’s there to solve my mocking problem and decide upon a possible path.

The problem

I want my function mocker to present a uniform interface whether it’s mocking functions, static methods or instance methods. While patchwork makes an excellent job in the first two cases PHPUnit will be my workhorse for the last one.
Keeping in mind an objective code like

$spy = FunctionMocker::spy('SomeClass::instanceMethod', 23);



returning a vanilla PHPUnit-generated mock object will not make it because wasCalledTimes in neither a SomeClass method neither a PHPUnit mock object method. I need to add methods to the mock object returned from PHPUnit and I need to do it extending it.

Templating next

I will walk the same path PHPUnit walks creating a template for a class extending the mock object (which already took the pain to extend any class lying under it) and simply adding my interface methods to it.
In the most normal situation possible PHPUnit workflow would be:

  1. Use reflection to get class and method information about the class to mock
  2. From a template compile the PHP code for a class extending the base class with PHPUnit mock object specific methods
  3. Evaluate the code
  4. Create a new instance of the just defined class
  5. Return it

I will extend the mock object extending the base class adding my methods on top of PHPUnit ones repeating steps 2 to 5.

That’s pretty much the plan for the next step and the (passing) test below is a good proof of concept

     * @test
     * it should allow proxing method using an extension class
    public function it_should_allow_proxing_method_using_an_extension_class() {
        $mock = $this->getMockBuilder( __NAMESPACE__ . '\A' )->setMockClassName( 'ClassToBeWrapped' )->getMock();
        $mock->expects( $this->once() )->method( 'method' );
        $reflection    = new \ReflectionClass( $mock );
        $mockClassName = $reflection->name;
        $className     = 'WrapperClass';

        $code = <<< CODESET
        class $className extends $mockClassName {

            private \$__originalPhpunitMockObject;

            public function addedMethod() {
                return 23;

            public function method() {

            public function __functionMocker_setOriginalObject( \$object ) {
                \$this->__originalPhpunitMockObject = \$object;
        $ok   = eval( $code );

        $wrapper = new $className();
        $wrapper->__functionMocker_setOriginalObject( $mock );

        $this->assertEquals( 23, $wrapper->addedMethod() );

I appreciate your input