UDSSL

WordPress Redux Store Middleware Testing with Jest

UDSSL Timeslot tests are passing

First, a WordPress REST API should be created to handle requests from the app. Then a Redux Store should be created using Redux Toolkit. We can create a redux store without Redux Toolkit. But we have to use a lot of boilerplate code. Middleware can be used to intercept the dispatched actions before reaching the store. Middleware can also dispatch additional actions if necessary. Let’s create 3 simple middleware. Finally, let’s write some tests with Jest for the store implementation.

WordPress Redux Store Middleware Testing Explainer

Inside WordPress posts or pages, a shortcode can be used to display the React component attached to the store.

[udssl_redux]

The complete working code for this article can be found on GitHub. wp-redux-store-middleware-jest

WordPress Redux Store Testing with Jest

The basic four steps are as follows.

  1. Create WordPress REST API

    • GET request
    • PATCH request
  2. Create a Redux Store with Redux Toolkit

    • Using Redux Toolkit
    • Using Redux Devtools
  3. Create Three Middleware to Redux Store

    • API Middleware
    • Log Middleware
    • Toast Middleware
  4. Write Tests for the store with Jest

    • Unit Tests and Social Tests
    • Using Axios Mock Adapter

Registering WordPress REST Routes

register_rest_route() can be used to register a REST route in WordPress.

register_rest_route( 'udssl/v1',
    '/timeslots/(?P<id>\d+)?',
    array(
        'methods' => 'PATCH',
        'callback' => 'handle_udssl_api_patch',
    )
)

This function is to be hooked to rest_api_init function.

Complete file on GitHub: udssl-rest-api.php

Using a WordPress Shortcode to attach a React Component

add_shortcode() function can be used to create a shortcode.

add_shortcode('udssl_redux', 'udssl_render_react_component')`

Localizing the Javascript Bundle

All of the Javascript should be bundled into one file with Webpack. If you need to pass some data into the Javascript, then you should wp_localize_script() with WordPress.

wp_enqueue_script( 'udssl_wp_react_bundle',
    plugins_url('dist/bundle.js', __FILE__),
    array(),
    false,
    true
);

wp_localize_script( 'udssl_wp_react_bundle',
    'udssl_localize',
    array(
        'resturl' => get_rest_url( null, 'udssl/v1/' ),
        'ajaxurl' => admin_url( 'admin-ajax.php' ),
    )
);

Then we can use the data/urls in our application. For example we can pass the resturl as the baseURL of Axios requests.

const response = await axios.request({
  baseURL: udssl_localize.resturl,
  url,
  method,
  data,
})

Creating the Store

Import the configureStore from Redux Toolkit.

import { configureStore } from '@reduxjs/toolkit'

use configureStore() function to create a store.

Creating Store Slices

createSlice() function from Redux Toolkit can be used to create a store slice. Without this function we have to write a lot of boilerplate code.

We should give it a name, an initial state and a set of actions. In this store, there are three slices. (timeslots, projects and users)

Creating the First Middleware for the Redux Store

This simple middleware logs all the dispatched actions in the browser console. It’s a very simple middleware. The entire middleware is as follows.

const logger = params => store => next => action => {
  console.log("Logging: ", params)
  console.log("next: ", next)
  console.log("action: ", action)
  return next(action)
}

export default logger

There are three middleware in this application. The API middleware which is responsible for calling remote API is a bit complex. See it here: api.js

Attaching the Middleware to the Store

All the middleware should be attached to the store with configureStore() function.

Writing a Unit Test for Timeslots Slice Actions

Jest is used to write tests. You can describe the test as follows.

describe("timeslotsSlice", () => {
  describe("action creators", () => {
    it("should addTimeslot", () => {})
  })
})

Complete test on GitHub: timeslots.spec.js

Using Redux Developer Tools

Redux Dev Tools Extention is a useful tool for developing redux applications.

Redux Dev Tools Extension

Writing Social Tests for Store Actions with FakeAxios

Redux Store Testing with Fake Axios

Unit tests are good for testing individual actions. If you need to test a larger scope, then you should do social testing. FakeAxios can be used to mock API calls.

fakeAxios.onGet("/timeslots").reply(() => {
  expect(timeslotsSlice().loading).toBe(true)
  return [200, [{ id: 1 }]]
})

Analyzing Code Coverage

jest --coverage can be used generate a test code coverage report. See below screenshot.

UDSSL WordPress Jest Coverage

Jest can also generate the HTML report of the code coverage. lcov-report

UDSSL WordPress Redux Jest Coverage HTML

References

  1. WordPress
  2. React
  3. Redux
  4. Redux Toolkit
  5. Jest

The complete repository of this article is on GitHub. wp-redux-store-middleware-jest

git clone https://github.com/UDSSL/wp-redux-store-middleware-jest.git`

Written by UDSSL