Unit testing functions that call WordPress core functions

Viewed 15

Need to write a php unit test for init().

namespace My\Space;

class MyClass{
   public function init(){
       add_action('my_hook','my_function',10,0);
   }
}

All the test needs to do is assert that add_action() was called with the correct parameters. If add_action() was a method of another class (lets call it class WP_Functions), then an instance of that class could be passed into the constructor of MyClass and used in init() to do the add_action(). If so, Unit testing could pass in a mock of WP_Functions that asserts that add_action() be called with the desired input parameters. But now that add_action() is not a class method, what is the best solution?

Here is what I've tried:

  • Let add_action() run as it is defined by WordPress. Remove actions from my_hook, call init() and then assert all the correct values are set in $wp_filter['my_hook']. Simple enough for the above case but gets complicated for functions that have conditions and/or add/remove many hooks/filters.

  • Define mock version add_action() in the My\Space namespace and make it simply var_dump() the input parameters. Then all the test needs to do is expect that init() will outputs the var_dump for the desired parameters. This works well but requires add_action() be redefined for every namespace in which its used. This becomes difficult to manage when there are many namespaces and/or many other functions similar to add_action() that require mock versions. Also can get complicated if the callback function is member of MyClass such that it is specified as [ $this, 'callback_name' ]. Plus, it utilizes var_dump() for a non-intended purpose.

  • Create a public method of MyClass that called add_action that calls the WordPress add_action(). If so, testing can create a mock of MyClass that expects it's add_action method to be called with the desired parameters. However, this requires an extra function call. Plus it would require every class that calls add_action() to somehow have it's own add_action method.

Is there a better solution?

0 Answers
Related