# Table of Contents - [Introduction | WP_Mock](#introduction-wp-mock) - [Installation | WP_Mock](#installation-wp-mock) - [Configuration | WP_Mock](#configuration-wp-mock) - [Mocking WordPress Functions | WP_Mock](#mocking-wordpress-functions-wp-mock) - [Mocking WordPress Objects | WP_Mock](#mocking-wordpress-objects-wp-mock) - [Mocking WordPress Hooks | WP_Mock](#mocking-wordpress-hooks-wp-mock) - [Mocking WordPress Constants | WP_Mock](#mocking-wordpress-constants-wp-mock) - [WP_Mock Test Case | WP_Mock](#wp-mock-test-case-wp-mock) - [Introduction | WP_Mock](#introduction-wp-mock) - [Mocking WordPress Functions | WP_Mock](#mocking-wordpress-functions-wp-mock) - [WP_Mock Test Case | WP_Mock](#wp-mock-test-case-wp-mock) --- # Introduction | WP_Mock [](https://wp-mock.gitbook.io/documentation/#what-is-wp_mock) What is WP\_Mock ----------------------------------------------------------------------------------- [WP\_Mock](https://github.com/10up/wp_mock) is a unit test tool for PHP projects that extend or build upon [WordPress](https://wordpress.org/) , such as plugins, themes, or even whole websites. WP\_Mock helps mock common WordPress functions and components, making it easier to write unit tests for your project. It also helps perform additional assertions over your code that are not part of the standard toolset. When writing code for WordPress, it so often happens that the code you create needs to invoke a WordPress function, class or hook, which is external code you are integrating your project with. Ideally, though, a unit test will not depend on WordPress being loaded in order to test your 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. [NextInstallation](https://wp-mock.gitbook.io/documentation/getting-started/installation) Last updated 2 years ago --- # Installation | WP_Mock [](https://wp-mock.gitbook.io/documentation/getting-started/installation#requirements) Requirements -------------------------------------------------------------------------------------------------------- * PHP 7.4+ * Composer 2.0+ [](https://wp-mock.gitbook.io/documentation/getting-started/installation#install-wp_mock) Install WP\_Mock --------------------------------------------------------------------------------------------------------------- Add WP\_Mock as a dev-dependency using Composer: Copy composer require --dev 10up/wp_mock [](https://wp-mock.gitbook.io/documentation/getting-started/installation#dependencies) Dependencies -------------------------------------------------------------------------------------------------------- WP\_Mock needs the following dependencies to work: * PHPUnit ^9.5 (BSD 3-Clause license) * Mockery ^1.6 (BSD 3-Clause license) * Patchwork ^2.1 (MIT license) They will be installed for you by Composer. Next, you will need to configure PHPUnit first before enabling WP\_Mock. [Consult PHPUnit documentation](https://phpunit.de/documentation.html) for this step. You will also need to [configure WP\_Mock with a bootstrap file](https://wp-mock.gitbook.io/documentation/getting-started/configuration) to use it in your tests. [PreviousIntroduction](https://wp-mock.gitbook.io/documentation) [NextConfiguration](https://wp-mock.gitbook.io/documentation/getting-started/configuration) Last updated 1 year ago --- # Configuration | WP_Mock After installing WP\_Mock you will need to perform some simple configuration steps before you can start using it in your tests. [](https://wp-mock.gitbook.io/documentation/getting-started/configuration#bootstrap-wp_mock) Bootstrap WP\_Mock -------------------------------------------------------------------------------------------------------------------- Before you can start using WP\_Mock to test your code, you'll need to bootstrap the library by creating a bootstrap.php file. Here is an example of a bootstrap you might use: Copy post_content : 'Post not found'; } } You can use `WP_Mock::userFunction()` to mock the `get_post()` function and return a mock post object: Copy use MyPlugin\MyClass; use stdClass use WP_Mock; final class MyClassTest extends WP_Mock\Tools\TestCase { public function testMyFunction() : void { $post = new stdClass(); $post->post_content = 'Hello World'; WP_Mock::userFunction('get_post') ->once() ->with(123) ->andReturn($post); $this->assertSame('Hello World', (MyClass::myFunction(123)); } } 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: Copy return \WP_Mock\Functions\Handler::handleFunction(__FUNCTION__, func_get_args()); **Important!** You should typically extend `WP_Mock\Tools\TestCase` instead of `PHPUnit\Framework\TestCase` when using WP\_Mock. See [WP\_Mock Test Case Documentation](https://wp-mock.gitbook.io/documentation/tools/wp-mock-test-case) and [how to configure WP\_Mock](https://wp-mock.gitbook.io/documentation/getting-started/configuration) for more information. [](https://wp-mock.gitbook.io/documentation/usage/using-wp-mock#using-mockery-expectations) 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](http://docs.mockery.io/en/latest/reference/expectations.html) 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'`. Copy WP_Mock::userFunction('get_permalink')->once()->with(42)->andReturn('https://example.com/foo'); [](https://wp-mock.gitbook.io/documentation/usage/using-wp-mock#using-expectations-in-arguments) 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. ### [](https://wp-mock.gitbook.io/documentation/usage/using-wp-mock#arguments) 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. #### [](https://wp-mock.gitbook.io/documentation/usage/using-wp-mock#examples) 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. Copy use WP_Mock; WP_Mock::userFunction('get_post_meta', [\ 'times' => 1,\ 'args' => [WP_Mock\Functions::type('int'), 'some_meta_key', true],\ ) );\ \ WP_Mock::userFunction('get_post_meta', [\ 'times' => 1,\ 'args' => [WP_Mock\Functions::type('int'), 'another_meta_key', true], \ ) );\ \ ### \ \ [](https://wp-mock.gitbook.io/documentation/usage/using-wp-mock#times)\ \ 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.\ \ ### \ \ [](https://wp-mock.gitbook.io/documentation/usage/using-wp-mock#return)\ \ 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.\ \ #### \ \ [](https://wp-mock.gitbook.io/documentation/usage/using-wp-mock#example)\ \ Example\ \ Copy\ \ WP_Mock::userFunction('get_post_meta', [\ 'return' => function($post_id, $key, $single) {\ if ($key === 'some_meta_key') {\ return 'some value';\ }\ \ return 'another value';\ }\ ) );\ \ ### \ \ [](https://wp-mock.gitbook.io/documentation/usage/using-wp-mock#return-in-order)\ \ 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`.\ \ #### \ \ [](https://wp-mock.gitbook.io/documentation/usage/using-wp-mock#example-1)\ \ Example\ \ Copy\ \ WP_Mock::userFunction('is_single', [\ 'return_in_order' => [true, false],\ ]);\ \ $this->assertTrue(is_single());\ $this->assertFalse(is_single());\ $this->assertFalse(is_single()); // All subsequent calls will use the last defined return value\ \ ### \ \ [](https://wp-mock.gitbook.io/documentation/usage/using-wp-mock#return-argument)\ \ 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`.\ \ #### \ \ [](https://wp-mock.gitbook.io/documentation/usage/using-wp-mock#example-2)\ \ Example\ \ Copy\ \ WP_Mock::userFunction('sanitize_title', [\ 'return_arg' => 0,\ ]);\ \ // ...\ \ sanitize_title($title); // WP_Mock will have this function return the value of $title as-is\ \ [PreviousConfiguration](https://wp-mock.gitbook.io/documentation/getting-started/configuration)\ [NextMocking WordPress Hooks](https://wp-mock.gitbook.io/documentation/usage/mocking-wp-action-and-filter-hooks)\ \ Last updated 1 year ago --- # Mocking WordPress Objects | WP_Mock Mocking calls to `wpdb`, `WP_Query`, etc. can be done using the [Mockery](https://github.com/padraic/mockery) framework. While this isn't part of WP Mock itself, complex code will often need these objects and this framework will let you incorporate those into your tests. Since WP Mock requires Mockery, it should already be included as part of your installation. [](https://wp-mock.gitbook.io/documentation/usage/mocking-wp-objects#an-example-with-wpdb) An example with `WPDB` ---------------------------------------------------------------------------------------------------------------------- Let's say we have a function that gets three post IDs from the database. Copy namespace MyPlugin; class MyClass { public function getSomePostIds() : array { global $wpdb; return $wpdb->get_col("SELECT ID FROM {$wpdb->posts} LIMIT 3"); } } When we mock the `$wpdb` object, we're not performing an actual database call, only mocking the results. We need to call the `get_col` method with an SQL statement, and return three arbitrary post IDs. Copy use Mockery; use MyPlugin\MyClass; final class MyClassTest extends \WP_Mock\Tools\TestCase { public function testCanGetSomePostIds() : void { global $wpdb; $wpdb = Mockery::mock('WPDB'); $wpdb->posts = 'wp_posts'; $wpdb->allows('get_col') ->once() ->with('SELECT ID FROM wp_posts LIMIT 3') ->andReturn([1, 2, 3]); $postIds = (new MyClass())->getSomePostIds(); $this->assertEquals([1, 2, 3], $postIds); } } [PreviousMocking WordPress Hooks](https://wp-mock.gitbook.io/documentation/usage/mocking-wp-action-and-filter-hooks) [NextMocking WordPress Constants](https://wp-mock.gitbook.io/documentation/usage/mocking-wp-constants) Last updated 1 year ago --- # Mocking WordPress Hooks | WP_Mock The [hooks and filters of the WordPress Plugin API](http://codex.wordpress.org/Plugin_API) are common (and preferred) entry points for third-party scripts, and WP\_Mock makes it easy to test that these are being registered and executed within your code. [](https://wp-mock.gitbook.io/documentation/usage/mocking-wp-action-and-filter-hooks#ensuring-actions-and-filters-are-registered) Ensuring actions and filters are registered ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Rather than attempting to mock `add_action()` or `add_filter()`, WP\_Mock has built-in support for both of these functions: instead, use `WP_Mock::expectActionAdded()` and `WP_Mock::expectFilterAdded()`, respectively. In the following example, our expectations will fail if the `MyClass::addHooks()` method do not call `add_action('save_post', [$this, 'myActionCallback'], 10, 2 )` _and_ `add_action('the_content', [$this, 'myFilterCallback'])`: Copy use MyPlugin\MyClass; use WP_Mock\Tools\TestCase as TestCase; final class MyClassTest extends TestCase { public function testHookExpectations() : void { $classInstance = new MyClass(); WP_Mock::expectActionAdded('save_post', [$classInstance, 'myActionCallback'], 10, 2); WP_Mock::expectFilterAdded('the_content', [$classInstance, 'myFilterCallback']); $classInstance->addHooks(); } } It's important to note that the `$priority` and `$parameter_count` arguments (parameters 3 and 4 for both `add_action()` and `add_filter()`) are significant. If in our example our code used a different priority or a different number of arguments when setting the callbacks, the test would have failed. If the actual instance of an expected class cannot be passed, `AnyInstance` can be used: Copy WP_Mock::expectFilterAdded('the_content', [new \WP_Mock\Matcher\AnyInstance(Special::class), 'the_content']); [](https://wp-mock.gitbook.io/documentation/usage/mocking-wp-action-and-filter-hooks#asserting-that-closures-have-been-added-as-hook-callbacks) Asserting that closures have been added as hook callbacks -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Sometimes it's handy to add a [Closure](https://secure.php.net/manual/en/class.closure.php) as a WordPress hook instead of defining a function in the global namespace. To assert that such a hook has been added, you can perform assertions referencing the Closure class or a `callable` type: Copy public function testAnonymousHookCallback() : void { WP_Mock::expectActionAdded('save_post', WP_Mock\Functions::type('callable')); WP_Mock::expectActionAdded('save_post', WP_Mock\Functions::type(Closure::class)); WP_Mock::expectFilterAdded('the_content', WP_Mock\Functions::type('callable')); WP_Mock::expectFilterAdded('the_content', WP_Mock\Functions::type(Closure::class)); } [](https://wp-mock.gitbook.io/documentation/usage/mocking-wp-action-and-filter-hooks#asserting-that-actions-and-filters-are-applied) Asserting that actions and filters are applied ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Now that we're testing if we are adding actions and/or filters, the next step is to ensure our code is calling those hooks when expected. For actions, we'll want to listen for `do_action()` to be called for our action name, so we'll use `WP_Mock::expectAction()`: Copy public function testActionCallingFunction() : void { WP_Mock::expectAction('my_action'); MyClass::myMethod(); } This test will fail if `MyClass::myMethod()` does not call `do_action('my_action')`. In situations where your code needs to trigger actions, this assertion makes sure the appropriate hooks are being triggered. For filters, we can inject our own response to `apply_filters()` using `WP_Mock::onFilter()`. Take the code below, for example: Copy namespace MyPlugin; class MyClass { public function filterContent() : string { return apply_filters('custom_content_filter', 'This is unfiltered'); } } We can test that the filter is being applied by using `WP_Mock::onFilter()`: Copy use MyPlugin\MyClass; use WP_Mock; use WP_Mock\Tools\TestCase as TestCase; final class MyClassTest extends TestCase { public function testCanFilterContent() : void { WP_Mock::onFilter('custom_content_filter') ->with('This is unfiltered') ->reply('This is filtered'); $content = (new MyClass())->filterContent(); $this->assertEquals('This is filtered', $content); } } We can also use the `withAnyArgs` method to test that the filter is being applied. This is particularly useful in test cases where we do not care about the arguments but just its return value. This can be done like so: Copy use MyPlugin\MyClass; use WP_Mock; use WP_Mock\Tools\TestCase as TestCase; final class MyClassTest extends TestCase { public function testCanFilterContent() : void { WP_Mock::onFilter('custom_content_filter') ->withAnyArgs() ->reply('This is filtered'); $content = (new MyClass())->filterContent(); $this->assertEquals('This is filtered', $content); } } Alternatively, there is a method `WP_Mock::expectFilter()` that will add a bare assertion that the filter will be applied without changing the value: Copy namespace MyPlugin; class MyClass { public function filterContent() : string { $value = apply_filters( 'custom_content_filter', 'Default' ); if ($value === 'Default') { do_action('default_value'); } return $value; } } And then the test: Copy use MyPlugin\MyClass; use WP_Mock; use WP_Mock\Tools\TestCase as TestCase; final class MyClassTest extends TestCase { public function testCanFilterContent() : void { WP_Mock::expectFilter('custom_content_filter', 'Default'); WP_Mock::expectAction('default_value'); $this->assertEquals('Default', (new MyClass())->filterContent()); } } [](https://wp-mock.gitbook.io/documentation/usage/mocking-wp-action-and-filter-hooks#asserting-that-an-object-has-been-passed) Asserting that an object has been passed ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- To assert that an object has been added as an argument, you can perform assertions referencing the object's class type. Take the code below, for example: Copy namespace MyPlugin; class MyClass { public function filterContent() : NewClass { return apply_filters('custom_content_filter', new NewClass()); } } class NewClass { public function __construct() { echo 'New Class'; } } We can do this: Copy use WP_Mock; use WP_Mock\Tools\TestCase as TestCase; use MyPlugin\MyClass; use MyPlugin\NewClass; final class MyClassTest extends TestCase { public function testAnonymousObject() : void { WP_Mock::expectFilter('custom_content_filter', WP_Mock\Functions::type(NewClass::class)); $this->assertInstanceOf(NewClass::class, (new MyClass())->filterContent()); $this->assertConditionsMet(); } } [PreviousMocking WordPress Functions](https://wp-mock.gitbook.io/documentation/usage/using-wp-mock) [NextMocking WordPress Objects](https://wp-mock.gitbook.io/documentation/usage/mocking-wp-objects) Last updated 8 months ago --- # Mocking WordPress Constants | WP_Mock Certain constants need to be mocked, otherwise various WordPress functions will attempt to include files that just don't exist. For example, nearly all uses of the `WP_Http` API require first including: Copy ABSPATH . WPINC . '/class-http.php' If these constants are not set, and files do not exist at the location they specify, functions referencing them will produce a fatal error. By default, WP\_Mock will [mock the following constants](https://github.com/10up/wp_mock/blob/trunk/docs/usage/php/WP_Mock/API/constant-mocks.php) : Constant Default mocked value `WP_CONTENT_DIR` `__DIR__ . '/dummy-files'` `ABSPATH` `''` `WPINC` `__DIR__ . '/dummy-files/wp-includes'` `EZSQL_VERSION` `'WP1.25'` `OBJECT` `'OBJECT'` `Object` `'OBJECT'` `object` `'OBJECT'` `OBJECT_K` `'OBJECT_K'` `ARRAY_A` `'ARRAY_A'` `ARRAY_N` `'ARRAY_N'` WP\_Mock provides a few dummy files, located in the `./php/WP_Mock/API/dummy-files/` directory. These files are used to mock the `WP_CONTENT_DIR` and `WPINC` constants, as shown in the table above. The `! defined` check is used for all constants, so that individual test environments can override the normal default by setting constants in a bootstrap configuration file. [PreviousMocking WordPress Objects](https://wp-mock.gitbook.io/documentation/usage/mocking-wp-objects) [NextWP\_Mock Test Case](https://wp-mock.gitbook.io/documentation/tools/wp-mock-test-case) Last updated 2 years ago --- # WP_Mock Test Case | WP_Mock WP\_Mock comes with a base test case class that provides a number of useful methods for testing WordPress plugins and themes. This class is located in the `WP_Mock\Tools\TestCase` namespace, and can be used by extending it in your test classes: Copy use WP_Mock\Tools\TestCase as TestCase; final class MyTestCase extends TestCase { // ... } WP\_Mock `TestCase` extends PHPUnit own `TestCase` so all methods and assertions from the latter are available in the former. On top of those, WP\_Mock `TestCase` will include a collection of handy methods for helping you test your code. [](https://wp-mock.gitbook.io/documentation/tools/wp-mock-test-case#methods) Methods ----------------------------------------------------------------------------------------- ### [](https://wp-mock.gitbook.io/documentation/tools/wp-mock-test-case#assert-conditions-met) Assert conditions met The `TestCase::assertConditionsMet()` function will assert that the current test conditions have been met. This is useful when your test assertions are purely WP\_Mock expectations, and you don't want to have to call `Mockery::close()` in your test, otherwise PHPUnit might raise a warning that no assertions were performed. Copy use WP_Mock\Tools\TestCase as TestCase; final class MyTestCase extends TestCase { public function testMyFunction() : void { WP_Mock::userFunction('my_function', ['times' => 1]); $this->assertConditionsMet(); } } ### [](https://wp-mock.gitbook.io/documentation/tools/wp-mock-test-case#assert-equals-html) Assert equals HTML The `TestCase::assertEqualsHtml()` function will evaluate a string as HTML and compare it to another string. This is useful when you want to compare HTML strings that may have different formatting, but are otherwise identical. Copy use WP_Mock\Tools\TestCase as TestCase; final class MyTestCase extends TestCase { public function testMyFunction() : void { $this->assertEqualsHtml('
Test
', '
Test
'); } } ### [](https://wp-mock.gitbook.io/documentation/tools/wp-mock-test-case#expect-output-string) Expect output string The `TestCase::expectOutputString()` function will assert that the output of a function matches a given string. This is useful when you want to test the output of a function that echoes HTML. Copy use WP_Mock\Tools\TestCase as TestCase; final class MyTestCase extends TestCase { public function testMyFunction() : void { $this->expectOutputString('
Test
'); echo '
Test
'; } } ### [](https://wp-mock.gitbook.io/documentation/tools/wp-mock-test-case#mock-static-method) Mock static method The `TestCase::mockStaticMethod()` function will mock a static method on a class, via Patchwork, returning a Mockery object. Copy use WP_Mock\Tools\TestCase as TestCase; final class MyTestCase extends TestCase { public function testMyFunction() : void { $mock = $this->mockStaticMethod('MyClass', 'myStaticMethod'); $mock->expects($this->once())->willReturn('test'); $this->assertEquals('test', MyClass::myStaticMethod()); } } ### [](https://wp-mock.gitbook.io/documentation/tools/wp-mock-test-case#access-inaccessible-class-members) Access inaccessible class members The following methods can be used to access methods or properties of classes that are inaccessible (private or protected), using [Reflection](https://www.php.net/manual/en/book.reflection.php) : #### [](https://wp-mock.gitbook.io/documentation/tools/wp-mock-test-case#get-or-invoke-an-inaccessible-method) Get or invoke an inaccessible method Use the following methods to get and invoke an inaccessible (private or protected) method from a class through [`ReflectionMethod`](https://www.php.net/manual/en/class.reflectionmethod.php) : Copy use WP_Mock\Tools\TestCase as TestCase; final class MyTestCase extends TestCase { public function testMyFunction() : void { $class = new MyClass(); // myMethod() is private or protected - this will return a ReflectionMethod object $method = $this->getInaccessibleMethod($class, 'myMethod'); // will invoke MyClass::myMethod() $method->invoke($class); // shortcut method to consolidate the above in a single call (assumes this method returns a string) $this->assertEquals('test', $this->invokeInaccessibleMethod($class, 'myMethod')); } } #### [](https://wp-mock.gitbook.io/documentation/tools/wp-mock-test-case#handle-inaccessible-properties) Handle inaccessible properties Similar to the methods above, there is a similar collection of test methods that will use [`ReflectionProperty`](https://www.php.net/manual/en/class.reflectionproperty.php) to manipulate inaccessible (private or protected) class properties: Copy use WP_Mock\Tools\TestCase as TestCase; final class MyTestCase extends TestCase { public function testMyProperty() : void { $class = MyClass(); // $myProperty is private or protected - this will return a ReflectionProperty object $property = $this->getInaccessibleProperty($class, 'myProperty'); // invoke MyClass::$myProperty $this->assertEquals('foo', $property->getValue($class)); // shortcut method to consolidate the above in a single call $this->assertEquals('foo', $this->getInaccessiblePropertyValue($class, 'myProperty')); // set MyClass::$myProperty to 'bar' $this->setInaccessibleProperty($class, get_class($class), 'myProperty', 'bar'); // shortcut for the above $this->setInaccessiblePropertyValue($class, 'myProperty', 'bar'); } } [PreviousMocking WordPress Constants](https://wp-mock.gitbook.io/documentation/usage/mocking-wp-constants) Last updated 2 years ago --- # Introduction | WP_Mock [](https://wp-mock.gitbook.io/documentation/getting-started#what-is-wp_mock) What is WP\_Mock -------------------------------------------------------------------------------------------------- [WP\_Mock](https://github.com/10up/wp_mock) is a unit test tool for PHP projects that extend or build upon [WordPress](https://wordpress.org/) , such as plugins, themes, or even whole websites. WP\_Mock helps mock common WordPress functions and components, making it easier to write unit tests for your project. It also helps perform additional assertions over your code that are not part of the standard toolset. When writing code for WordPress, it so often happens that the code you create needs to invoke a WordPress function, class or hook, which is external code you are integrating your project with. Ideally, though, a unit test will not depend on WordPress being loaded in order to test your 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. [NextInstallation](https://wp-mock.gitbook.io/documentation/getting-started/installation) Last updated 2 years ago --- # Mocking WordPress Functions | WP_Mock 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. [](https://wp-mock.gitbook.io/documentation/usage#mocking-wordpress-core-functions) 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. Copy namespace MyPlugin; class MyClass { public function myFunction(int $postId) : string { $post = get_post($postId); return $post ? $post->post_content : 'Post not found'; } } You can use `WP_Mock::userFunction()` to mock the `get_post()` function and return a mock post object: Copy use MyPlugin\MyClass; use stdClass use WP_Mock; final class MyClassTest extends WP_Mock\Tools\TestCase { public function testMyFunction() : void { $post = new stdClass(); $post->post_content = 'Hello World'; WP_Mock::userFunction('get_post') ->once() ->with(123) ->andReturn($post); $this->assertSame('Hello World', (MyClass::myFunction(123)); } } 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: Copy return \WP_Mock\Functions\Handler::handleFunction(__FUNCTION__, func_get_args()); **Important!** You should typically extend `WP_Mock\Tools\TestCase` instead of `PHPUnit\Framework\TestCase` when using WP\_Mock. See [WP\_Mock Test Case Documentation](https://wp-mock.gitbook.io/documentation/tools/wp-mock-test-case) and [how to configure WP\_Mock](https://wp-mock.gitbook.io/documentation/getting-started/configuration) for more information. [](https://wp-mock.gitbook.io/documentation/usage#using-mockery-expectations) 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](http://docs.mockery.io/en/latest/reference/expectations.html) 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'`. Copy WP_Mock::userFunction('get_permalink')->once()->with(42)->andReturn('https://example.com/foo'); [](https://wp-mock.gitbook.io/documentation/usage#using-expectations-in-arguments) 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. ### [](https://wp-mock.gitbook.io/documentation/usage#arguments) 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. #### [](https://wp-mock.gitbook.io/documentation/usage#examples) 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. Copy use WP_Mock; WP_Mock::userFunction('get_post_meta', [\ 'times' => 1,\ 'args' => [WP_Mock\Functions::type('int'), 'some_meta_key', true],\ ) );\ \ WP_Mock::userFunction('get_post_meta', [\ 'times' => 1,\ 'args' => [WP_Mock\Functions::type('int'), 'another_meta_key', true], \ ) );\ \ ### \ \ [](https://wp-mock.gitbook.io/documentation/usage#times)\ \ 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.\ \ ### \ \ [](https://wp-mock.gitbook.io/documentation/usage#return)\ \ 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.\ \ #### \ \ [](https://wp-mock.gitbook.io/documentation/usage#example)\ \ Example\ \ Copy\ \ WP_Mock::userFunction('get_post_meta', [\ 'return' => function($post_id, $key, $single) {\ if ($key === 'some_meta_key') {\ return 'some value';\ }\ \ return 'another value';\ }\ ) );\ \ ### \ \ [](https://wp-mock.gitbook.io/documentation/usage#return-in-order)\ \ 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`.\ \ #### \ \ [](https://wp-mock.gitbook.io/documentation/usage#example-1)\ \ Example\ \ Copy\ \ WP_Mock::userFunction('is_single', [\ 'return_in_order' => [true, false],\ ]);\ \ $this->assertTrue(is_single());\ $this->assertFalse(is_single());\ $this->assertFalse(is_single()); // All subsequent calls will use the last defined return value\ \ ### \ \ [](https://wp-mock.gitbook.io/documentation/usage#return-argument)\ \ 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`.\ \ #### \ \ [](https://wp-mock.gitbook.io/documentation/usage#example-2)\ \ Example\ \ Copy\ \ WP_Mock::userFunction('sanitize_title', [\ 'return_arg' => 0,\ ]);\ \ // ...\ \ sanitize_title($title); // WP_Mock will have this function return the value of $title as-is\ \ [PreviousConfiguration](https://wp-mock.gitbook.io/documentation/getting-started/configuration)\ [NextMocking WordPress Hooks](https://wp-mock.gitbook.io/documentation/usage/mocking-wp-action-and-filter-hooks)\ \ Last updated 1 year ago --- # WP_Mock Test Case | WP_Mock WP\_Mock comes with a base test case class that provides a number of useful methods for testing WordPress plugins and themes. This class is located in the `WP_Mock\Tools\TestCase` namespace, and can be used by extending it in your test classes: Copy use WP_Mock\Tools\TestCase as TestCase; final class MyTestCase extends TestCase { // ... } WP\_Mock `TestCase` extends PHPUnit own `TestCase` so all methods and assertions from the latter are available in the former. On top of those, WP\_Mock `TestCase` will include a collection of handy methods for helping you test your code. [](https://wp-mock.gitbook.io/documentation/tools#methods) Methods ----------------------------------------------------------------------- ### [](https://wp-mock.gitbook.io/documentation/tools#assert-conditions-met) Assert conditions met The `TestCase::assertConditionsMet()` function will assert that the current test conditions have been met. This is useful when your test assertions are purely WP\_Mock expectations, and you don't want to have to call `Mockery::close()` in your test, otherwise PHPUnit might raise a warning that no assertions were performed. Copy use WP_Mock\Tools\TestCase as TestCase; final class MyTestCase extends TestCase { public function testMyFunction() : void { WP_Mock::userFunction('my_function', ['times' => 1]); $this->assertConditionsMet(); } } ### [](https://wp-mock.gitbook.io/documentation/tools#assert-equals-html) Assert equals HTML The `TestCase::assertEqualsHtml()` function will evaluate a string as HTML and compare it to another string. This is useful when you want to compare HTML strings that may have different formatting, but are otherwise identical. Copy use WP_Mock\Tools\TestCase as TestCase; final class MyTestCase extends TestCase { public function testMyFunction() : void { $this->assertEqualsHtml('
Test
', '
Test
'); } } ### [](https://wp-mock.gitbook.io/documentation/tools#expect-output-string) Expect output string The `TestCase::expectOutputString()` function will assert that the output of a function matches a given string. This is useful when you want to test the output of a function that echoes HTML. Copy use WP_Mock\Tools\TestCase as TestCase; final class MyTestCase extends TestCase { public function testMyFunction() : void { $this->expectOutputString('
Test
'); echo '
Test
'; } } ### [](https://wp-mock.gitbook.io/documentation/tools#mock-static-method) Mock static method The `TestCase::mockStaticMethod()` function will mock a static method on a class, via Patchwork, returning a Mockery object. Copy use WP_Mock\Tools\TestCase as TestCase; final class MyTestCase extends TestCase { public function testMyFunction() : void { $mock = $this->mockStaticMethod('MyClass', 'myStaticMethod'); $mock->expects($this->once())->willReturn('test'); $this->assertEquals('test', MyClass::myStaticMethod()); } } ### [](https://wp-mock.gitbook.io/documentation/tools#access-inaccessible-class-members) Access inaccessible class members The following methods can be used to access methods or properties of classes that are inaccessible (private or protected), using [Reflection](https://www.php.net/manual/en/book.reflection.php) : #### [](https://wp-mock.gitbook.io/documentation/tools#get-or-invoke-an-inaccessible-method) Get or invoke an inaccessible method Use the following methods to get and invoke an inaccessible (private or protected) method from a class through [`ReflectionMethod`](https://www.php.net/manual/en/class.reflectionmethod.php) : Copy use WP_Mock\Tools\TestCase as TestCase; final class MyTestCase extends TestCase { public function testMyFunction() : void { $class = new MyClass(); // myMethod() is private or protected - this will return a ReflectionMethod object $method = $this->getInaccessibleMethod($class, 'myMethod'); // will invoke MyClass::myMethod() $method->invoke($class); // shortcut method to consolidate the above in a single call (assumes this method returns a string) $this->assertEquals('test', $this->invokeInaccessibleMethod($class, 'myMethod')); } } #### [](https://wp-mock.gitbook.io/documentation/tools#handle-inaccessible-properties) Handle inaccessible properties Similar to the methods above, there is a similar collection of test methods that will use [`ReflectionProperty`](https://www.php.net/manual/en/class.reflectionproperty.php) to manipulate inaccessible (private or protected) class properties: Copy use WP_Mock\Tools\TestCase as TestCase; final class MyTestCase extends TestCase { public function testMyProperty() : void { $class = MyClass(); // $myProperty is private or protected - this will return a ReflectionProperty object $property = $this->getInaccessibleProperty($class, 'myProperty'); // invoke MyClass::$myProperty $this->assertEquals('foo', $property->getValue($class)); // shortcut method to consolidate the above in a single call $this->assertEquals('foo', $this->getInaccessiblePropertyValue($class, 'myProperty')); // set MyClass::$myProperty to 'bar' $this->setInaccessibleProperty($class, get_class($class), 'myProperty', 'bar'); // shortcut for the above $this->setInaccessiblePropertyValue($class, 'myProperty', 'bar'); } } [PreviousMocking WordPress Constants](https://wp-mock.gitbook.io/documentation/usage/mocking-wp-constants) Last updated 2 years ago ---