As part of my redux action, it makes several sequential api requests. The apiCall
method returns a Promise with some value, and that value is used by a subsequent apiCall
to make another request, and so on. I'm using Jest to test these api calls.
const myAPI = {
apiCall(param: any): Promise<any> {
return new Promise((resolve, reject) => {
resolve('result');
});
},
};
const serialAPIRequests = () => {
myAPI.apiCall('first_param')
.then((result) => {
console.log(result);
return myAPI.apiCall(result);
})
.then((result) => {
console.log(result);
return myAPI.apiCall(result);
})
.then((result) => {
console.log(result);
return Promise.resolve(result);
});
};
I am trying to write a test to ensure apiCall
has been called the correct number of times and with the right parameters.
describe.only('my test', () => {
it('should test api stuff', () => {
myAPI.apiCall = jest.fn()
.mockReturnValueOnce(Promise.resolve('result1'))
.mockReturnValueOnce(Promise.resolve('result2'))
.mockReturnValueOnce(Promise.resolve('result3'));
serialAPIRequests();
expect(myAPI.apiCall).toHaveBeenCalledTimes(3);
});
});
What happens is that Jest report Expected mock function to have been called three times, but it was called one time.
Jest test result shows that
● Console
console.log
result1
console.log
result2
console.log
result3
● my test › should test api stuff
expect(jest.fn()).toHaveBeenCalledTimes(3)
Expected mock function to have been called three times, but it was called one time.
The fact that console.log showed different values means the mocked return was properly passed through the mock function and it was called 3 times.
What could be causing this and how do I properly test this function?
Use async/await to test async code. Read more here: https://facebook.github.io/jest/docs/en/tutorial-async.html
describe.only('my test', () => {
it('should test api stuff', async () => {
myAPI.apiCall = jest.fn()
.mockReturnValueOnce(Promise.resolve('result1'))
.mockReturnValueOnce(Promise.resolve('result2'))
.mockReturnValueOnce(Promise.resolve('result3'));
await serialAPIRequests();
expect(myAPI.apiCall).toHaveBeenCalledTimes(3);
});
});
Promises are async so by the time you do you check the mock was actually called once.
You could do this instead. Wait for all calls to be done and return a promise to indicate the test is async.
return serialAPIRequests().then(() => {
expect(myAPI.apiCall).toHaveBeenCalledTimes(3);
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With