score:3

Accepted answer

here is the unit test solution:

api.middleware.ts:

import { middleware } from 'redux';
import axios from 'axios';
import { api_request } from './actiontypes';
import { apisuccess, apierror } from './actioncreator';

export const apimiddleware: middleware = ({ dispatch }) => (next) => async (action): promise<void> => {
  next(action);

  if (action.type.includes(api_request)) {
    const body = action.payload;
    const { url, method, feature } = action.meta;

    try {
      const response = await axios({ method, url, data: body });
      dispatch(apisuccess({ response, feature }));
    } catch (error) {
      console.error(error);
      dispatch(apierror({ error, feature }));
    }
  }
};

actiontypes.ts:

export const api_request = 'api_request';
export const api_request_success = 'api_request_success';
export const api_request_failure = 'api_request_failure';

actioncreator.ts:

import { api_request_success, api_request_failure } from './actiontypes';

export function apisuccess(data) {
  return {
    type: api_request_success,
    ...data,
  };
}
export function apierror(data) {
  return {
    type: api_request_failure,
    ...data,
  };
}

api.middleware.test.ts:

import { apimiddleware } from './api.middleware';
import axios from 'axios';
import { middlewareapi } from 'redux';
import { api_request, api_request_success, api_request_failure } from './actiontypes';

jest.mock('axios', () => jest.fn());

describe('59754838', () => {
  aftereach(() => {
    jest.clearallmocks();
  });
  describe('#apimiddleware', () => {
    describe('unit test', () => {
      it('should dispatch api success action', async () => {
        const store: middlewareapi = { dispatch: jest.fn(), getstate: jest.fn() };
        const next = jest.fn();
        const action = {
          type: api_request,
          payload: {},
          meta: { url: 'http://localhost', method: 'get', feature: 'feature' },
        };
        const mresponse = { name: 'user name' };
        (axios as jest.mocked<any>).mockresolvedvalueonce(mresponse);
        await apimiddleware(store)(next)(action);
        expect(next).tobecalledwith(action);
        expect(axios).tobecalledwith({ method: action.meta.method, url: action.meta.url, data: action.payload });
        expect(store.dispatch).tobecalledwith({
          type: api_request_success,
          response: mresponse,
          feature: action.meta.feature,
        });
      });

      it('should dispatch api error action', async () => {
        const store: middlewareapi = { dispatch: jest.fn(), getstate: jest.fn() };
        const next = jest.fn();
        const action = {
          type: api_request,
          payload: {},
          meta: { url: 'http://localhost', method: 'get', feature: 'feature' },
        };
        const merror = new error('network error');
        (axios as jest.mocked<any>).mockrejectedvalueonce(merror);
        await apimiddleware(store)(next)(action);
        expect(next).tobecalledwith(action);
        expect(axios).tobecalledwith({ method: action.meta.method, url: action.meta.url, data: action.payload });
        expect(store.dispatch).tobecalledwith({
          type: api_request_failure,
          error: merror,
          feature: action.meta.feature,
        });
      });
    });
  });
});

unit test results with coverage report:

 pass  src/stackoverflow/59754838/api.middleware.test.ts (11.206s)
  59754838
    #apimiddleware
      unit test
        ✓ should dispatch api success action (21ms)
        ✓ should dispatch api error action (23ms)

  console.error src/stackoverflow/59754838/api.middleware.ts:3460
    error: network error
        at /users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/59754838/api.middleware.test.ts:42:24
        at step (/users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/59754838/api.middleware.test.ts:33:23)
        at object.next (/users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/59754838/api.middleware.test.ts:14:53)
        at /users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/59754838/api.middleware.test.ts:8:71
        at new promise (<anonymous>)
        at object.<anonymous>.__awaiter (/users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/59754838/api.middleware.test.ts:4:12)
        at object.<anonymous> (/users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/59754838/api.middleware.test.ts:34:46)
        at object.asyncjesttest (/users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/jasmineasyncinstall.js:102:37)
        at resolve (/users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queuerunner.js:43:12)
        at new promise (<anonymous>)
        at mapper (/users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queuerunner.js:26:19)
        at promise.then (/users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queuerunner.js:73:41)
        at process._tickcallback (internal/process/next_tick.js:68:7)

-------------------|----------|----------|----------|----------|-------------------|
file               |  % stmts | % branch |  % funcs |  % lines | uncovered line #s |
-------------------|----------|----------|----------|----------|-------------------|
all files          |      100 |       50 |      100 |      100 |                   |
 actioncreator.ts  |      100 |      100 |      100 |      100 |                   |
 actiontypes.ts    |      100 |      100 |      100 |      100 |                   |
 api.middleware.ts |      100 |       50 |      100 |      100 |                 9 |
-------------------|----------|----------|----------|----------|-------------------|
test suites: 1 passed, 1 total
tests:       2 passed, 2 total
snapshots:   0 total
time:        12.901s

source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59754838


Related Query

More Query from same tag