Testing functions with expect()
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).

Expectations on times a function is called

1
Functions\expect('paganini')->once();
2
​
3
Functions\expect('tween')->twice();
4
​
5
Functions\expect('who_knows')->zeroOrMoreTimes();
6
​
7
Functions\expect('i_should_run')->atLeast()->once();
8
​
9
Functions\expect('i_have_a_max')->atMost()->twice();
10
​
11
Functions\expect('poor_me')->never();
12
​
13
Functions\expect('pretty_precise')->times(3);
14
​
15
Functions\expect('i_have_max_and_min')->between(2, 4);
Copied!
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.
1
// allow anything
2
Functions\expect('function_name')
3
->once()
4
->withAnyArgs();
5
​
6
// allow nothing
7
Functions\expect('function_name')
8
->once()
9
->withNoArgs();
10
​
11
// validate specific arguments
12
Functions\expect('function_name')
13
->once()
14
->with('arg_1', 'arg2');
15
​
16
// validate specific argument types
17
Functions\expect('function_name')
18
->times(3)
19
->with(Mockery::type('resource'), Mockery::type('int'));
20
​
21
// validate anything in specific places
22
Functions\expect('function_name')
23
->zeroOrMoreTimes()
24
->with(Mockery::any());
25
​
26
// validate a set of given arguments
27
Functions::expect('function_name')
28
->once()
29
->with(Mockery::anyOf('a', 'b', 'c'));
30
​
31
// regex validation
32
Functions\expect('function_name')
33
->once()
34
->with('/^foo/');
35
​
36
// excluding specific values
37
Functions\expect('function_name')
38
->once()
39
->with(Mockery::not(2, 3));
40
​
41
// dealing with array arguments
42
Functions\expect('function_name')
43
->once()
44
->with(Mockery::hasKey('foo'), Mockery::contains('bar', 'baz'));
Copied!

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:
1
// return a specific value
2
Functions\expect('function_name')
3
->once()
4
->with('foo', 'bar')
5
->andReturn('Baz!');
6
​
7
// return values in order
8
Functions\expect('function_name')
9
->twice()
10
->andReturn('First time I run', 'Second time I run');
11
​
12
// return values in order, alternative
13
Functions\expect('function_name')
14
->twice()
15
->andReturnValues(['First time I run', 'Second time I run']);
16
​
17
// return noting
18
Functions::expect('function_name')
19
->twice()
20
->andReturnNull();
21
​
22
// use a callback for returning a value
23
Functions\expect('function_name')
24
->atLeast()
25
->once()
26
->andReturnUsing(function() {
27
return 'I am an alias!';
28
});
29
​
30
// makes function throws an Exception (e.g. to test try statements)
31
Functions\expect('function_name')
32
->once()
33
->andThrow('RuntimeException'); // Both exception names and object are supported
Copied!
Last modified 2yr ago