Often, in tests, what we need is not only to enforce a function returned value (what Functions\when() allows to do), but to test function behavior based on expectations.
Mockery has a very powerful, and human readable Domain Specific Language (DSL) that allows to set expectations on how object methods should behave, e.g. validate arguments they should receive, how many times they are called, and so on.
Brain Monkey brings that power to function testing. The entry-point is the Functions\expect() function.
It receives a function name and returns a Mockery expectation object with all its power.
Below there are just several examples, for the full story about Mockery expectations see its documentation.
Only note that in functions testing the shouldReceive Mockery method makes no sense, so don't use it (an exception will be thrown if you do that).
There is no need to explain how it works: Mockery DSL reads like plain English.
Of course, expectation on the times a function should run can be combined with arguments expectation.
Expectations on received arguments
Below a few examples, for the full story see Mockery docs.
// allow anythingFunctions\expect('function_name')->once()->withAnyArgs();// allow nothingFunctions\expect('function_name')->once()->withNoArgs();// validate specific argumentsFunctions\expect('function_name')->once()->with('arg_1','arg2');// validate specific argument typesFunctions\expect('function_name')->times(3)->with(Mockery::type('resource'),Mockery::type('int'));// validate anything in specific placesFunctions\expect('function_name')->zeroOrMoreTimes()->with(Mockery::any());// validate a set of given argumentsFunctions::expect('function_name')->once()->with(Mockery::anyOf('a','b','c'));// regex validationFunctions\expect('function_name')->once()->with('/^foo/');// excluding specific valuesFunctions\expect('function_name')->once()->with(Mockery::not(2,3));// dealing with array argumentsFunctions\expect('function_name')->once()->with(Mockery::hasKey('foo'),Mockery::contains('bar','baz'));
Forcing behavior
Excluding shouldReceive, all the Mockery expectation methods can be used with Brain Monkey, including andReturn or andReturnUsing used to enforce a function to return specific values during tests.
In fact, Functions\when() do same thing for simple cases when no expectations are required.
Again, just a few examples:
// return a specific valueFunctions\expect('function_name')->once()->with('foo','bar')->andReturn('Baz!');// return values in orderFunctions\expect('function_name')->twice()->andReturn('First time I run','Second time I run');// return values in order, alternativeFunctions\expect('function_name')->twice()->andReturnValues(['First time I run','Second time I run']);// return notingFunctions::expect('function_name')->twice()->andReturnNull();// use a callback for returning a valueFunctions\expect('function_name')->atLeast()->once()->andReturnUsing(function() {return'I am an alias!'; });// makes function throws an Exception (e.g. to test try statements)Functions\expect('function_name')->once()->andThrow('RuntimeException'); // Both exception names and object are supported