Function Mocker to support PHPUnit constraints

Trying to add a powerful and incredibly missing feature: PHPUnit constraints support.

The problem

The version of function-mocker available at the moment allows tests to do something PHPUnit doesn't easily allow out of the box: checking if a class method was called with certain arguments independently of the call position.

use tad\FunctionMocker\FunctionMocker as Test;


class MyTest extends \PHPUnit_Framework_TestCase {

    /**
     * @test
     * it should call various methods
     */
    public function it_should_call_various_methods()
    {
        $mock = Test::replace('SomeClass::methodC');

        $mock->methodA('lorem');
        $mock->methodB('ipsum');
        $mock->methodC('lorem');
        $mock->methodA('ipsum');
        $mock->methodB('foo');

        // this will pass: methodC was called with the string 'lorem'
        $mock->wasCalledWithOnce(['lorem'], 'methodC');

        // this will fail: methodC was NOT called with the 'foo' string
        $mock->wasCalledWithOnce(['foo'], 'methodC');

        // this will pass: methodA was called with the 'ipsum' string
        // the second time
        $mock->wasCalledWithOnce(['ipsum'], 'methodA');

        // this will also pass: methodA was called with the 'lorem' string
        // the first time
        $mock->wasCalledWithOnce(['lorem'], 'methodA');
    }
}

What function-mocker does not allow is to use the powerful PHPUnit constraints.

In work solution

I'm working to allow the syntax above to be used while also allowing for the use of constraints to check for method calls and arguments

use tad\FunctionMocker\FunctionMocker as Test;


class MyTest extends \PHPUnit_Framework_TestCase {

    /**
     * @test
     * it should call variuos methods
     */
    public function it_should_call_various_methods()
    {
        $mock = Test::replace('SomeClass::methodC');

        $mock->methodA('lorem');
        $mock->methodB('ipsum');
        $mock->methodC('lorem');
        $mock->methodA('ipsum');
        $mock->methodB('foo');

        // this will pass: methodC was called with a string
        $mock->wasCalledWithOnce([Test::isType('string')], 'methodC');

        // this will fail: methodC was NOT called with the an array
        $mock->wasCalledWithOnce([Test::isType('array']), 'methodC');

        // this will fail: methodA was called with the a string two times
        $mock->wasCalledWithOnce([Test::isType('string']), 'methodA');

        // this will pass: methodA was called with a string argument two times
        $mock->wasCalledWithTimes([Test::isType('string')], 2, 'methodA');
    }
}

Function Mocker is wrapping PHPUnit assertion and constraints methods to allow for a unified API; I like to alias FunctionMocker to Test for clarity. The use of constraints will extend beyond primitive types and will tap into the power of what's in PHPUnit already.