Reputation: 1331
I am trying to test a Vuex action that uses Promise.all to fetch data from an API, and then commits a mutation based on the response. However, both my assertion test (expect.assertions(1)
) and the test to see if the commit was called are failing.
My action is:
fetchUserProfile ({ dispatch, commit}) {
const userAccountFetch = api.get('/user/account');
const userProfileFetch = api.get('/user/profile');
const userItemsFetch = api.get(`/user/purchases`);
Promise.all([
userAccountFetch.catch((error) => {
console.error(error);
return { error, };
}),
userProfileFetch.catch((error) => {
console.error(error);
return { error, };
}),
userItemsFetch.catch((error) => {
console.error(error);
return { error, };
}),
]).then((responses) => {
commit('setUserAccount', {responses});
}
});
}
My test is as follows:
jest.mock('@api/api.js', () => ({ get: jest.fn(), }));
const mockApi = require('@api/api.js');
test('fetchUserProfile performs commit on successful fetch', () => {
const mockResponse = [{userAccount: ....}, {userProfile: ...}, {userItems: ....}];
mockApi.get.mockReturnValueOnce(Promise.resolve(mockResponse[0]));
mockApi.get.mockReturnValueOnce(Promise.resolve(mockResponse[1]));
mockApi.get.mockReturnValueOnce(Promise.resolve(mockResponse[2]));
expect.assertions(1);
fetchUserProfile({ commit, state, }).then(() => expect(commit).toHaveBeenCalledTimes(1));
});
I put console.logs throughout my action, and the test is making it down to the line where I perform my commit, but for some reason the test is not passing. I'm not sure what is wrong here. Any help would be tremendously appreciate.
Upvotes: 0
Views: 3962
Reputation: 222989
This is a very common antipattern that a function that uses promises doesn't return a promise that could be chained. This prevents it from being efficiently used and tested.
It should be:
return Promise.all(...)
Another problem is that Jest asynchronous test doesn't return a promise. This results in uncaught rejection that doesn't affect test result.
async..await
is the efficient way to maintain the order of execution; async
function always returns a promise:
test('fetchUserProfile performs commit on successful fetch', async () => {
....
await fetchUserProfile({ commit, state });
expect(commit).toHaveBeenCalledTimes(1);
});
Upvotes: 1