Debugging wrong WordPress calls in PHPUnit with WordPress’s ‘doing_it_wrong’

Recently I tried to debug some cryptic error messages that occurred at newly written unit tests. I’ve started to introduced some unit tests to the JSON API of a WordPress plugin. But the unit tests were failing with the quite meaningless message:

Unexpected incorrect usage notice for register_rest_route 
Failed asserting that an array is empty.

The problem was: I had no idea was this meant. So after some navigating through the internet and the WordPress core files, I discovered that there was a new constraint since WordPress 5.5. It is now necessary to specify a ‘permission_callback’ to every ‘register_rest_route’ call. So the solution to the problem was to add the following line to the ‘args’ of every ‘register_rest_route’ call:

'permission_callback' => '__return_true'

That actually solved the problem and I was able to run the tests successfully. Note, that this says, that the API endpoints are publicly accessible. The requirement to specify the permission happened intending to don’t accidentally expose private endpoints. In my case, this was the case so it’s fine.

But I was still a little bit unhappy about the awkward error finding process. I wanted to get the actual error from the WordPress core. The cool thing is: This is quite possible. There is a function called ‘doing_it_wrong’ that is called by WordPress whenever he discovers a bad usage of core functionality.

So I wrote an extension for the ‘WP_UnitTestCase’ class which allowed me to catch the information about which function caused the problem and where it is located.

class WP_DoinItWrong_TestCase extends \WP_UnitTestCase {
   public function setUp() {
      parent::setUp();
      add_action("doing_it_wrong_run", [$this, "_wp_doing_it_wrong"])
   }

   public function tearDown() {
      parent::tearDown();
      remove_action("doing_it_wrong_run", [$this, "_wp_doing_it_wrong"]);
   }

   public function _wp_doing_it_wrong($function, $message = "", $version = "") {
      $msg = "Youre Doing It Wrong at: $function ($version): $message" . "\n";

      foreach (debug_backtrace() as $traceIndex => $traceContent) {
         if(!$this->FilterStackTrace($traceIndex )) { continue;  }
         $msg .= sprintf("#%s '%s' at '%s'", $traceIndex , @$traceContent["function"], @$traceContent["file"]) . "\n";
      }

       $this->fail($msg);
   }

   protected function FilterStackTrace($index) {
      return true;
   }

}

A also added an overridable filter ‘FilterStackTrace’ so tests can specify which part of the StackTrace should be written to the log. This is optional but it can generate nice and specific error messages:

Youre Doing It Wrong at: register_rest_route ():
#5 'register_rest_route' at 'C:\Users\Alexa\Documents\dev\myplugin\DoingTheRegistration.php'

1 thought on “Debugging wrong WordPress calls in PHPUnit with WordPress’s ‘doing_it_wrong’”

Leave a Comment

Your email address will not be published. Required fields are marked *