Closure return values in function-mocker

Function-mocker uses closures to set return values: need I say more?

No mappings

A method PHPUnit supplies and function-mocker does not supply is the possibility to set a return value map when replacing method (or a function or a static method in function-mocker case).
Luckily the sentence above is not true; function-mocker allows the return value to be set either to a value like this

FunctionMocker::replace('someFunction', 23); $this->assertEquals(23, someFunction()); 

or to a callback function like this

FunctionMocker::replace('someFunction', function($arg){ return $arg * 2; }); $this->assertEquals(46, someFunction(23)); 

and this second possibility is the one that can be leveraged to create an argument to return value map.
The FunctionMocker::replace method will pass the arguments the function is called with to the closure, that’s what’s being used in the example above.

Using closure return values

If I want to stub out a function, a static method or an instance method to return a value in a map the possibility offered by a closure function makes the thing trivial

$map = [ 1 => ['plain' => 'Lorem', 'bold' => '<b>Lorem</b>'], 2 => ['plain' => 'Ipsum', 'bold' => '<b>Ipsum</b>'], ]; FunctionMocker::replace('Post::getContent', function($id, $format) use ($map){ return $map[$id][$format]; }) $this->assertEquals('Lorem', Post::getContent(1, 'plain')); $this->assertEquals('<b>Lorem</b>', Post::getContent(1, 'bold')); $this->assertEquals('Ipsum', Post::getContent(2, 'plain')); 

But since it’s a closure I’m dealing with I can pack way more logic in it and use the full power of the anonymous function to, as an example, simulate a lagging response

FunctionMocker::replace('Feed::getLatest', function() use($feedStub){ sleep(2); return $feedStub; }) 

or change the behaviour of the return value over time

FunctionMocker::replace('TwitterApi::queryFor', function($tag) use (&$calls, $messageTemplate){ if($calls > 5) { return ['status' => 0, 'message' => 'API query limit reached']; } $calls += 1; $message = str_replace('%%tag%%', $tag, $messageTemplate); return ['status' => 1, 'message' => $message]; }) 

So, using a lambda function, sky is the limit.

I appreciate your input