Better instance mocking in Function Mocker 01

A necessity for slicker instance method mocking born out of use.

The problem

The current version of function-mocker allows for the replacement of instance methods using a syntax like

FunctionMocker::replace('SomeClass::someMethod', function(){
    return 'foo';
    });

but the implementation has two limits.

Same mocks

The first limit is that replacing the same class again like this

$mock1 = FunctionMocker::replace('SomeClass::someMethod');
$mock2 = FunctionMocker::replace('SomeClass::anotherMethod');

will yield the same instance

$mock1 === $mock2;

This is sometimes the wanted effect but will block any attempt to get more than one mock of the same class per test, a limit.

Overhead on instance methods

The same example above fails at delivering a quick and clear replacing API; PHPUnit allows for batch replacement of methods and I would not like Function Mocker to be a step back from that possibility. Furthermore the more methods need to be replaced the more the overhead builds over PHPUnit

FunctionMocker::replace('SomeClass::methodOne');
FunctionMocker::replace('SomeClass::methodTwo');
FunctionMocker::replace('SomeClass::methodThree');
// each replacement will return the same object...
$mock = FunctionMocker::replace('SomeClass::methodFour');

//PHPUnit version
$this->getMock('SomeClass', ['methodOne', 'methodTwo', 'methodThree', 'methodFour']);

Chain solution

I’m thinking the thing out but a good API could be a chained one

$mock = FunctionMocker::startReplacing('SomeClass')
    ->method('methodOne')
    ->method('methodTwo')
    ->method('methodThree')
    ->method('methodFoour')
    ->get();

that would also allow for return values or callback functions to be set on a per-method base

$mock = FunctionMocker::startReplacing('SomeClass')
    ->method('methodOne', 'foo')
    ->method('methodTwo', 23)
    ->method('methodThree', function($arg){ return $arg > 1; })
    ->method('methodFoour', function($arg1, $arg2){ return $arg1 + $args2; })
    ->get();

I will devote some thought and time to the experiment and see what comes out of it.