Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion docs/usage/mocking-wp-action-and-filter-hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,25 @@ final class MyClassTest extends TestCase
$this->assertEquals('Default', (new MyClass())->filterContent());
}
}
```
```

## Asserting that actions and filters have been removed

Similarly, we can test that actions and filters are removed when expected, e.g.removing another plugin's admin notice. This is done using `WP_Mock::expectActionRemoved()` and `WP_Mock::expectFilterRemoved()`. Or conversely, we can confirm that they have _not_ been removed using `WP_Mock::expectActionNotRemoved()` and `WP_Mock::expectFilterNotRemoved()`. The latter functions are useful where a function being tested returns early in some scenarios, and we want to ensure that the hooks are not removed in that case.

```php
use MyPlugin\MyClass;
use WP_Mock\Tools\TestCase as TestCase;

final class MyClassTest extends TestCase
{
public function testRemoveAction() : void
{
$classInstance = new MyClass();

WP_Mock::expectActionRemoved('admin_notices', 'invasive_admin_notice');

$classInstance->removeInvasiveAdminNotice();
}
}
```
84 changes: 84 additions & 0 deletions php/WP_Mock.php
Original file line number Diff line number Diff line change
Expand Up @@ -546,4 +546,88 @@ public static function getDeprecatedMethodListener(): DeprecatedMethodListener
{
return static::$deprecatedMethodListener;
}

/**
* Adds an expectation that an action should be removed.
*
* @param string $action the action hook name
* @param string|callable-string|callable|Type $callback the callable to be removed
* @param int|Type|null $priority the priority it should be registered at
*
* @return void
* @throws InvalidArgumentException
*/
public static function expectActionRemoved(string $action, $callback, $priority = null) : void
Comment thread
BrianHenryIE marked this conversation as resolved.
Outdated
{
self::userFunction(
'remove_action',
array(
'args' => array_filter(func_get_args()),
'times' => 1,
)
);
Comment thread
BrianHenryIE marked this conversation as resolved.
Outdated
}

/**
* Adds an expectation that an action should not be removed.
*
* @param string $action the action hook name
* @param null|string|callable-string|callable|Type $callback the callable to be removed
* @param int|Type|null $priority optional priority for the registered callback that is being removed
*
* @return void
* @throws InvalidArgumentException
*/
public static function expectActionNotRemoved(string $action, $callback, $priority = null) : void
{
self::userFunction(
'remove_action',
array(
'args' => array_filter(func_get_args()),
'times' => 0,
)
);
}

/**
* Adds an expectation that a filter should be removed.
*
* @param string $filter the filter name
* @param string|callable-string|callable|Type $callback the callable to be removed
* @param int|Type|null $priority the registered priority
*
* @return void
* @throws InvalidArgumentException
*/
public static function expectFilterRemoved(string $filter, $callback, $priority = null) : void
{
self::userFunction(
'remove_filter',
array(
'args' => array_filter(func_get_args()),
'times' => 1,
)
);
}

/**
* Adds an expectation that a filter should not be removed.
*
* @param string $filter the filter name
* @param null|string|callable-string|callable|Type $callback the callable to be removed
* @param int|Type|null $priority optional priority for the registered callback that is being removed
*
* @return void
* @throws InvalidArgumentException
*/
public static function expectFilterNotRemoved(string $filter, $callback, $priority = null) : void
{
self::userFunction(
'remove_filter',
array(
'args' => array_filter(func_get_args()),
'times' => 0,
)
);
}
}
56 changes: 56 additions & 0 deletions tests/Integration/WP_MockTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -335,4 +335,60 @@ public function testCanExpectHooksNotAdded() : void

$this->assertConditionsMet();
}

/**
* @covers \WP_Mock::expectActionRemoved()
* @covers \WP_Mock::expectFilterRemoved()
*
* @return void
* @throws Exception
*/
public function testCanExpectHooksRemoved() : void
{
WP_Mock::expectActionRemoved('wpMockTestActionWithCallbackAndPriority', 'wpMockTestFunction', 10);
WP_Mock::expectFilterRemoved('wpMockTestFilterWithCallbackAndPriority', 'wpMockTestFunction', 10);

WP_Mock::expectActionRemoved(
'wpMockTestActionWithCallbackAndAnyPriority',
'wpMockTestFunction',
\WP_Mock\Functions::type('int')
);
WP_Mock::expectFilterRemoved(
'wpMockTestFilterWithCallbackAndAnyPriority',
'wpMockTestFunction',
\WP_Mock\Functions::type('int')
);

WP_Mock::expectActionRemoved('wpMockTestActionWithCallbackAndDefaultPriority', 'wpMockTestFunction');
WP_Mock::expectFilterRemoved('wpMockTestFilterWithCallbackAndDefaultPriority', 'wpMockTestFunction');

remove_action('wpMockTestActionWithCallbackAndPriority', 'wpMockTestFunction', 10);
remove_filter('wpMockTestFilterWithCallbackAndPriority', 'wpMockTestFunction', 10);

remove_action('wpMockTestActionWithCallbackAndAnyPriority', 'wpMockTestFunction', rand(1,100));
remove_filter('wpMockTestFilterWithCallbackAndAnyPriority', 'wpMockTestFunction', rand(1,100));

remove_action('wpMockTestActionWithCallbackAndDefaultPriority', 'wpMockTestFunction');
remove_filter('wpMockTestFilterWithCallbackAndDefaultPriority', 'wpMockTestFunction');

$this->assertConditionsMet();
}

/**
* @covers \WP_Mock::expectActionNotRemoved()
* @covers \WP_Mock::expectFilterNotRemoved()
*
* @return void
* @throws Exception
*/
public function testCanExpectHooksNotRemoved() : void
{
WP_Mock::expectActionNotRemoved('wpMockTestActionWithCallbackAndPriority', 'wpMockTestFunction', 10);
WP_Mock::expectFilterNotRemoved('wpMockTestFilterWithCallbackAndPriority', 'wpMockTestFunction', 10);

WP_Mock::expectActionNotRemoved('wpMockTestActionWithCallbackAndDefaultPriority', 'wpMockTestFunction');
WP_Mock::expectFilterNotRemoved('wpMockTestFilterWithCallbackAndDefaultPriority', 'wpMockTestFunction');

$this->assertConditionsMet();
}
}