简体   繁体   中英

jest mocking promise method called wrong number of times

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?

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);
})

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);
      });
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM