问题
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: "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:
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: "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,
},
});
});
});
来源:https://stackoverflow.com/questions/65856663/how-to-jest-test-an-async-action-with-axios-in-react