Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
653 views
in Technique[技术] by (71.8m points)

reactjs - how to jest test an async action with axios in react?

I have an action-generator 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,
      },
    });
  }
}; 

the endpoint /api/users returns {token:'a_token_string'} on being successful.

How should i test this action-generator using jest ?

I tried doing this, 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: "[email protected]",
    password: "testPassword",
  };
  await store.dispatch(register(testUser)).then(() => {
    expect(store.getActions()[0]).toEqual({
      type: REGISTER_SUCCESS,
      payload: {
        token: "testToken",
        isAuthenticated: true,
        loading: false,
      },
    });
  });
});
question from:https://stackoverflow.com/questions/65856663/how-to-jest-test-an-async-action-with-axios-in-react

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You're quite close to get it done. The thing is you're mocking axios.post while your implementation is using directly from axios object. As long as you mock axios object then it would work as it should. Here is proposed changes, please check inline comments for things you should also change:

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: "[email protected]",
    password: "testPassword",
  };
  await store.dispatch(register(testUser)).then(() => {
    expect(store.getActions()[0]).toEqual({
      type: REGISTER_SUCCESS,
      payload: {
        token: "testToken",
        isAuthenticated: true,
        loading: false,
      },
    });
  });
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...