首页 > 解决方案 > 测试使用 Redux Thunk 和身份验证的 redux 操作

问题描述

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

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 函数必须以不同的方式调用。我不知道怎么做!

标签: reactjstestingreduxjestjsjasmine

解决方案


我会嘲笑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 });
   });
});

推荐阅读