Mocking WordPress Functions
With WP_Mock you can write your PHPUnit test cases as you normally would, but with the added benefit of being able to mock WordPress functions and classes.
Mocking WordPress core functions
Ideally, a unit test will not depend on WordPress being loaded in order to test our code. By constructing mocks, it's possible to simulate WordPress core functionality by defining their expected arguments, responses, the number of times they are called, and more. In WP_Mock, this is done via the WP_Mock::userFunction()
method:
Suppose you have the following method in your code that uses get_post()
to output some content.
You can use WP_Mock::userFunction()
to mock the get_post()
function and return a mock post object:
In the above example WP_Mock is expecting that the method MyClass::myFunction
, when invoked, it will in turn call get_post()
exactly once, with a single argument of 123
as passed to the method's only argument, and that will return the content of a hypothetical post having that ID.
Calling WP_Mock::userFunction()
will dynamically define the function for you if necessary, which means changes the internal WP_Mock API shouldn't break your mocks. If you really want to define your own function mocks, they should always end with this line:
Important!
You should typically extend WP_Mock\Tools\TestCase
instead of PHPUnit\Framework\TestCase
when using WP_Mock. See WP_Mock Test Case Documentation and how to configure WP_Mock for more information.
Using Mockery expectations
The WP_Mock::userFunction()
class will return a complete Mockery\Expectation
object with any expectations added to match the arguments passed to the function. This enables using Mockery methods to add expectations in addition to, or instead of using the arguments array passed to userFunction
.
For example, the invocation below will set the expectation that the get_permalink()
function will be called exactly once, with the argument 42
, and that it will return the string 'https://example.com/foo'
.
Using expectations in arguments
You can also pass an associative array of arguments to the second parameter of WP_Mock::userFunction()
to set expectations about the function's arguments, the number of times it should be called, and what it should return.
Arguments
The args
parameter sets expectations about what the arguments passed to the function should be. This value should always be an array with the arguments in order and, like with return, if you use a Closure
, its return value will be used to validate the argument expectations. You can also indicate that the argument can be any value of any type by using '*
'.
WP_Mock has several helper functions to make this feature more flexible. There are static methods on the WP_Mock\Functions
class meant for this:
Functions::type($type)
: Expects an argument of a certain type. This can be any core PHP data type (string
,int
,resource
,callable
, etc.) or any class or interface name.Functions::anyOf($values)
: Expects the argument to be any value in the$values
array.
Examples
In the following example, we're expecting get_post_meta()
twice: once each for some_meta_key
and another_meta_key
, where an integer (in this case, a post ID) is the first argument, the meta key is the second, and a boolean true
is the third.
Times
The times
argument, as shown in the previous examples, declares how many times the given function should be called. For an exact number of calls, use a non-negative, numeric value (e.g. 3
). If the function should be called a minimum number of times, append a plus-sign (+
, e.g. 7+
for seven or more calls). Conversely, if a mocked function should have a maximum number of invocations, append a minus-sign (-
) to the argument (e.g. 7-
for seven or fewer times).
You may also choose to specify a range, e.g. 3-6
would translate to "this function should be called between three and six times".
The default value for times
is 0+
, meaning the function should be called any number of times.
Return
The return
argument defines the value (if any) that the function should return. If you pass a Closure
as the return value, the function will return whatever the Closure's return value is.
Example
Return in order
The return_in_order
argument sets an array of values that should be returned with each subsequent call, useful if if your function will be called multiple times in the test but needs to return different values.
Note: Setting this value overrides whatever may be set return
.
Example
Return argument
You can use the return_arg
argument to specify that the function should return one of its arguments. return_arg
should be the position of the argument in the arguments array, so 0
for the first argument, 1
for the second, etc. You can also set this to true
, which is equivalent to 0
. This will override both return
and return_in_order
.
Example
Last updated