Testing Async Middleware
Let’s see how we can test async middleware.
For a more complete example, let’s use the following API middleware:
import axios from 'axios';
import { API } from 'consts';
import { apiStarted, apiFinished, apiError } from 'actions/ui';
const apiMiddleware = ({ dispatch, getState }) => next => action => {
if (action.type !== API) {
return next(action);
}
const { url, success } = action.payload;
const headers = {};
const accessToken = (getState() || {}).accessToken;
if (accessToken) {
headers['Access-Token'] = accessToken;
}
dispatch(apiStarted());
return axios.request({ url, headers })
.then(response => {
dispatch(success(JSON.parse(response.data)));
dispatch(apiFinished());
})
.catch(params => dispatch(apiError(new Error(params))));
};
export default apiMiddleware;
Our middleware catches any actions of type 'API'
. The API in question must contain a payload
key with a url
to request to and a success
parameter that holds an action creator to call with the returned data:
const setData = data => ({
type: 'SET_DATA',
payload: data
});
const apiAction = () => ({
type: API,
payload: {
success: setData,
url: 'fake.json'
}
});
In our Redux call, calling dispatch(apiAction())
will result in our API middleware submitting a GET
request for server/fake.json
and, if successful, dispatching the SET_DATA
action with the response set as payload
. When there is an error, an action created by apiError()
will be dispatched containing status
and statusText
.
API middleware will dispatch apiStarted()
before contacting the server and apiFinished()
on success (or apiError()
on failure). This allows the application to keep track of the number of active requests to the server and display a spinner or some other user indication.
To fully test this middleware, we can split the tests into three groups: general tests, success tests, and failure tests.
Get hands-on with 1200+ tech skills courses.