测试使用 Redux Thunk 和身份验证的 redux 操作

Test redux actions which uses Redux Thunk and authentication

我对测试 React-Redux 还很陌生,我想测试我的 loadUser-action,它使用 redux-thunk 并调用具有 auth 中间件的端点。这是我想测试的代码:

export const loadUser = () => (dispatch, getState) => {
  dispatch({ type: USER_LOADING });

  axios
    .get('/auth/user', tokenConfig(getState))
    .then((res) =>
      dispatch({
        type: USER_LOADED,
        payload: res.data,
      })
    )
    .catch((err) => {
      console.log(err);
      dispatch({
        type: LOADING_FAILURE,
      });
    });
};

export const tokenConfig = (getState) => {
  const token = getState().auth.token;

  const config = {
    headers: {
      'Content-type': 'application/json',
    },
  };

  if (token) {
    config.headers['x-auth-token'] = token;
  }

  console.log('CONFIG', config);

  return config;
};

这是我到目前为止的测试:

import { mockStore } from '../../test/utils/mockStore';
import { USER_LOADED } from '../types/authTypes';
import { loadUser } from './authActions';

describe('loadUser', () => {
  fit('gets user', async () => {
    const store = mockStore();
    const tokenConfig = jest.fn();
    await store.dispatch(loadUser());
    const actions = store.getActions();
    expect(actions[0]).toEqual({ type: USER_LOADED, meta: {} });
  });
});

必须以不同的方式调用 tokenConfig 函数。我不知道怎么办!

我会嘲笑 axios,因为您不想在 运行 单元测试时进行实际的 API 调用,因为它会占用您服务器上的资源。同样通过模拟 axios,你不必模拟 tokenConfig.

这就是我在个人项目中的做法:

import { mockStore } from '../../test/utils/mockStore';
import { USER_LOADED, LOADING_FAILURE } from '../types/authTypes';
import { loadUser } from './authActions';
import axios from 'axios';

jest.mock('axios'); // mock axios library

describe('loadUser', () => {
  fit('gets user', async () => {
    const store = mockStore();
    axios.get.mockImplementationOnce(() => Promise.resolve({ data: {} })); // mock resolve success
    await store.dispatch(loadUser());
    const actions = store.getActions();
    expect(actions[0]).toEqual({ type: USER_LOADED, payload: {} });
  });

   it('handles api failure', () => {
    const store = mockStore();
    axios.get.mockImplementationOnce(() => Promise.reject('Error')); // mock error
    await store.dispatch(loadUser());
    const actions = store.getActions();
    expect(actions[0]).toEqual({ type: LOADING_FAILURE });
   });
});