Learn how to use PHPUnit to test your WordPress REST API endpoints. We cover setting up WP_UnitTestCase, mocking requests, and verifying secure responses.
Previously in this course, we explored Implementing Activity Logging: Auditing REST API Changes in WordPress to track data mutations. Now, we shift our focus from runtime logging to development-time verification by learning how to perform unit testing on your API endpoints.
If you have already followed the Unit Testing Foundations: Ensuring WordPress Plugin Stability, you are likely familiar with the standard testing scaffold. Today, we apply those principles to the REST API, ensuring our routes remain reliable as the codebase grows.
To test the REST API, you cannot simply call your callback functions directly. You must simulate the full routing lifecycle. The WP_REST_Request class and the WP_REST_Server are the core components here.
First, ensure your test suite inherits from WP_UnitTestCase. This base class provides the necessary hooks to reset the database and the global state between tests, which is critical for consistent API results.
PHPclass Test_Knowledge_Base_API extends WP_UnitTestCase { protected $server; public function setUp(): void { parent::setUp(); #6A9955">// Access the global REST server global $wp_rest_server; $this->server = $wp_rest_server = new WP_REST_Server(); do_action('rest_api_init'); } }
By manually instantiating WP_REST_Server and triggering rest_api_init, we ensure that our plugin's routes are registered before any test runs.
When testing an endpoint—such as the one we built in Creating POST Endpoints for Data Submission in WordPress REST API—we need to verify both the status code and the structure of the JSON response.
Here is how you dispatch a request programmatically and assert the outcome:
PHPpublic function test_get_kb_items_returns_data() { #6A9955">// 1. Create a dummy post for the test $post_id = $this->factory->post->create(['post_type' => 'kb_item']); #6A9955">// 2. Prepare the request $request = new WP_REST_Request('GET', '/kb/v1/items'); #6A9955">// 3. Dispatch the request through the server $response = $this->server->dispatch($request); #6A9955">// 4. Run assertions $this->assertEquals(200, $response->get_status()); $data = $response->get_data(); $this->assertIsArray($data); $this->assertEquals($post_id, $data[0]['id']); }
One of the most powerful features of WP_UnitTestCase is the ability to spoof the current user. Since most endpoints rely on permission_callback, you need to test both authorized and unauthorized states.
Use wp_set_current_user() to simulate different user levels:
PHPpublic function test_unauthorized_user_cannot_create_item() { #6A9955">// Set current user to a subscriber(lacks 'edit_posts' capability) $user_id = $this->factory->user->create(['role' => 'subscriber']); wp_set_current_user($user_id); $request = new WP_REST_Request('POST', '/kb/v1/items'); $request->set_param('title', 'Test Title'); $response = $this->server->dispatch($request); #6A9955">// Assert that the API returns a 403 Forbidden $this->assertEquals(403, $response->get_status()); }
Using the Knowledge Base plugin project:
GET endpoint you created earlier.tests/ directory if you haven't already.rest_api_init: If your tests fail with a "No route was found" error, it usually means your plugin's register_rest_route calls haven't been triggered in the test environment. Ensure do_action('rest_api_init') is called in setUp().factory methods ($this->factory->post->create()) to generate data. These methods ensure data is cleaned up automatically, preventing test pollution.WP_REST_Request bypasses some browser-based security checks, your code might still check for nonces. You may need to inject a valid nonce into the request object using $request->set_header('X-WP-Nonce', wp_create_nonce('wp_rest')).By incorporating these testing patterns, you ensure that your API remains a stable contract for your React frontend. Testing your endpoints is the final gatekeeper for code quality in a decoupled architecture.
Up next: We will move to the client side and learn how to perform Unit Testing for React Components, ensuring our UI logic is as robust as our backend.
Learn how to test React components in WordPress. We'll set up Jest, mock API services, and verify UI behavior to ensure your plugin's admin dashboard is stable.
Read moreMaster date and time in your React admin screens. Learn to use @wordpress/date to format, localize, and manage timestamps in your WordPress plugins.
Unit Testing API Endpoints