General Tests

Learn to build general tests to test async middleware.

The first test for any middleware is to ensure that it passes unknown actions down the chain. If we forget to use next(action), no actions will reach the reducers:

// Verifying unknown actions are handled correctly
it('should ignore non-API actions', () => {
  const sampleAction = { type: 'SAMPLE_ACTION' };

  middleware(sampleAction);

  // dispatch calls should be 0 
expect(dispatch.mock.calls.length).toBe(0);
  // next calls should be equal to sampleAction
   expect(next.mock.calls).toEqual([[sampleAction]]);
});

We must verify that dispatch() does not get called and that next() is called exactly once with our sampleAction. Since we will be using dispatch.mock.calls and next.mock.calls very often in our tests, we can shorten them a little by adding the following to our setup code:

// Improving the setup code
let next, dispatch, middleware, dispatchCalls, nextCalls;
//before Each function
beforeEach(() => {
  next          = jest.fn();
  dispatch      = jest.fn();

  dispatchCalls = dispatch.mock.calls;
  nextCalls     = next.mock.calls;

  middleware    = apiMiddleware({ dispatch })(next);
});

Now instead of expect(next.mock.calls) we can use expect(nextCalls).

Another general test could be to verify that the API_STARTED action is dispatched every time the middleware is about to access the server:

// Testing that API_STARTED is dispatched
it('should dispatch API_STARTED', () => {
  middleware(apiAction());
  // dispatch call should be API_STARTED
  expect(dispatchCalls[0]).toEqual([{ type: API_STARTED }]);
});

Our expect() call only checks that the first dispatch() action is API_STARTED because the middleware might call additional actions later.

Get hands-on with 1200+ tech skills courses.