Test done hooks
Testing framework agnostic
Brain Monkey can be used with any testing framework. Examples in this page will use PHPUnit, but the concepts are applicable to any testing framework.
Also note that test classes in this page extends the class MyTestCase
that is assumed very similar to the one coded in the WordPress / Setup docs section.
Simple tests with did_action()
and Filters\applied()
did_action()
and Filters\applied()
To check hooks have been fired, the only available WordPress function is did_action()
, it doesn't exist any did_filter()
or applied_filter()
.
To overcome the missing counter part of did_action()
for filters, Brain Monkey has a method accessible via Brain\Monkey\Filters\applied()
that does what you might expect.
Assuming a class like the following:
It can be tested using:
As you can guess from test code above, did_action()
and Filters\applied()
return the number of times an action or a filter has been triggered, just like did_action()
does in WordPress, but there's no way to use them to check which arguments were passed to the fired hook.
So, did_action()
and Filters\applied()
are fine for simple tests, mostly because using them you don't need to recall Brain Monkey methods, but they are not very powerful: arguments checking and, above all, the ability to respond to fired hooks are pivotal tasks to proper test WordPress code.
In Brain Monkey those tasks can be done testing fired hooks with expectations.
Test fired hooks with expectations
A powerful testing mechanism for fired hooks is provided by Brain Monkey thanks to Mockery expectations.
The entry points to use it are the Actions\expectDone()
and Filters\expectApplied()
functions.
As usual, below there a just a couple of examples, for the full story see Mockery docs.
Assuming the MyClass
above in this page, it can be tested with:
Just a couple of things...
expectations must be set before the code to be tested runs: they are called "expectations" for a reason
argument validation done using
with()
, validates hook arguments, not function arguments, it means what is passed todo_action
orapply_filters
excluding hook name itself
Respond to filters
Yet again, Brain Monkey, when possible, tries to make WordPress functions it redefines behave in the same way of real WordPress functions.
Brain Monkey apply_filters
by default returns the first argument passed to it, just like WordPress function does when no callback is added to the filter.
However, sometimes in tests is required that a filter returns something different.
Luckily, Mockery provides andReturn()
and andReturnUsing()
expectation methods that can be used to make a filter return anything.
See Mockery docs for more information.
Brain Monkey also provides the helper andReturnFirstArg()
that can be used to make a filter expectation behave like WordPress does: return first argument received:
Note that in the example right above, the expectation would not be necessary; in fact, the assertion verify either way because it is the default behavior of WordPress and Brain Monkey.
But this is very helpful what we want to set expectations and returned values for filters based on some received arguments, for example:
Finally note that when setting different expectations for same filter, but for different received arguments, an expectation is required to be set for all the arguments that the filter is going to receive. For example this will fail:
The reason for failing is that there's no expectation set when the filter receives "Meh!"
.
In such case, andReturnFirstArg()
comes useful again, to set a "catch all" expectation:
Respond to actions
To return a value from a filter is routine, not so for actions.
In fact, do_action()
always returns null
so, if Brain Monkey would allow a mocked returning value for do_action()
expectations, it would be in contrast with real WordPress code, with disastrous effects on tests.
So, don't try to use neither andReturn()
or andReturnUsing()
with Actions\expectDone()
because it will throw an exception.
However, sometimes one may be in the need do something when code calls do_action()
, like WordPress actually does.
This is the reason Brain Monkey introduces whenHappen()
method for action expectations. The method takes a callback to be ran when an action is fired.
Let's assume a class like the following:
It is possible write a test like this:
Resolving current_filter()
, doing_action
and doing_filter()
current_filter()
, doing_action
and doing_filter()
When WordPress is not performing an hook, current_filter()
returns false
.
And so does the Brain Monkey version of that function.
Now I want to surprise you: current_filter()
correctly resolves to the correct hook during the execution of any callback added to respond to hooks.
Let's assume a class like the following:
It is possible write a test like this:
Like magic, inside our callback, current_filter()
returns the right hook just like it does in WordPress. Note this will also work with any callback passed to whenHappen()
.
Surprised? There's more: inside callbacks used to respond to actions and filters, doing_action()
and doing_filter()
works as well!
Assuming a class like the following:
It is possible to write a test like this:
Last updated