如何在反应中用 axios 开玩笑测试异步操作?

时间:2021-01-23 07:06:10

标签: reactjs testing jestjs

我有一个动作生成器 register.js:

import { REGISTER_SUCCESS, REGISTER_FAIL } from "./types";
import axios from "axios";

export const register = (formData) => async (dispatch) => {
  const { name, email, password } = formData;
  const configRegister = {
    method: "post",
    url: "/api/users",
    headers: { "Content-Type": "application/json" },
    data: { name, email, password },
  };
  try {
    const res = await axios(configRegister);
    const token = res.data.token;
    dispatch({
      type: REGISTER_SUCCESS,
      payload: {
        token,
        isAuthenticated: true,
        loading: false,
      },
    });
  } catch (err) {
    console.error(err);
    dispatch({
      type: REGISTER_FAIL,
      payload: {
        token: null,
        isAuthenticated: false,
        loading: true,
      },
    });
  }
}; 

端点 /api/users 在成功时返回 {token:'a_token_string'}

我应该如何使用 jest 测试这个动作生成器?

我试过这样做,register.test.js :-

import {
  REGISTER_SUCCESS,
} from "./types";
import thunk from "redux-thunk";
import configureMockStore from "redux-mock-store";
import axios from "axios";

jest.mock("axios");
    
/** mock-store */
const createMockStore = configureMockStore([thunk]);
const defaultState = [];
const store = createMockStore(defaultState);
/** reset mock */
afterEach(() => jest.resetAllMocks());

test("should register a  user ", async () => {
  axios.post.mockImplementation(() => {
    return Promise.resolve({
      status: 200,
      body: {
        token: "testToken",
      },
    });
  });
  const res = await axios.post("/api/users");
  console.log(res.body);
  const testUser = {
    name: "testName",
    email: "test@email.com",
    password: "testPassword",
  };
  await store.dispatch(register(testUser)).then(() => {
    expect(store.getActions()[0]).toEqual({
      type: REGISTER_SUCCESS,
      payload: {
        token: "testToken",
        isAuthenticated: true,
        loading: false,
      },
    });
  });
});

1 个答案:

答案 0 :(得分:1)

你离完成它很近了。问题是您在模拟 axios.post 而您的实现直接从 axios 对象使用。只要您模拟 axios 对象,它就会正常工作。以下是建议的更改,请查看内嵌评论以了解您还应该更改的内容:

test("should register a user ", async () => {
  // Mock `axios` object directly
  axios.mockImplementation(() => {
    return Promise.resolve({
      status: 200,
      // should also change from `body` to `data` as well
      data: {
        token: "testToken",
      },
    });
  });
  
  // it will no longer work since the mock is changed
  // const res = await axios.post("/api/users");
  // console.log(res.body);

  const testUser = {
    name: "testName",
    email: "test@email.com",
    password: "testPassword",
  };
  await store.dispatch(register(testUser)).then(() => {
    expect(store.getActions()[0]).toEqual({
      type: REGISTER_SUCCESS,
      payload: {
        token: "testToken",
        isAuthenticated: true,
        loading: false,
      },
    });
  });
});