Reputation: 2185
I am trying to use Jest for unit testing. Part of the testing is to mock Axios, but for some reason it is not being called.
Here is my /__mocks__/axios.js
code:
export default {
post: jest.fn(() => Promise.resolve({})),
};
Here is my test code:
import mockAxios from 'axios';
import { registerUser } from '../../actions/auth';
import user from '../fixtures/user';
describe('Register User', () => {
test('Should call register API and redirect to login', async () => {
const historyMock = { push: jest.fn() };
mockAxios.post.mockImplementationOnce(() => Promise.resolve());
await registerUser(user, historyMock);
expect(mockAxios.post).toHaveBeenCalledTimes(1);
});
});
Also here is the registerUser code:
export const registerUser = (user, history) => dispatch => axios
.post('/users/register', user)
.then(() => history.push('/login'))
.catch((err) => {
dispatch(handleError(err));
});
But for some reason I continue to get the error:
Register User › Should call register API and redirect to login
expect(jest.fn()).toHaveBeenCalledTimes(1)
Expected mock function to have been called one time, but it was called zero times.
35 | await registerUser(user, historyMock);
36 |
> 37 | expect(mockAxios.post).toHaveBeenCalledTimes(1);
Any ideas why the mock is not working?
Upvotes: 3
Views: 11569
Reputation: 2185
As @jonrsharpe pointed out in the comments, the registerUser function was returning the function:
dispatch => axios
.post('/users/register', user)
.then(() => history.push('/login'))
.catch((err) => {
dispatch(handleError(err));
});
So in order for this to work, I had to had to mock the store using the redux-mock-store npm module. The new test code looks like:
import mockAxios from 'axios';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { setCurrentUser, registerUser } from '../../actions/auth';
import user from '../fixtures/user';
const defaultStoreState = { errors: {}, auth: { isAuthenticated: false, user: {} } };
const createMockStore = configureMockStore([thunk]);
describe('Register User', () => {
test('Should call register API and redirect to login', (done) => {
const mockStore = createMockStore(defaultStoreState);
const historyMock = { push: jest.fn() };
mockStore.dispatch(registerUser(user, historyMock)).then(() => {
expect(mockAxios.post).toHaveBeenCalledTimes(1);
expect(historyMock.push).toHaveBeenCalledTimes(1);
expect(historyMock.push).toHaveBeenCalledWith('/login');
done();
});
});
});
This gives a passing test now.
Upvotes: 2
Reputation: 415
I don't think you're setting the mock correctly.
mockAxios.post.mockImplementationOnce
should be changed to
mockAxios.post = jest.fn().mockResolvedValueOnce('bloofblurg');
Then you can double-check that post
has been called once and resolved the expected value.
expect(mockAxios.post).resolves.toBe('bloofblurg');
see
Upvotes: 1