最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - jest mocking promise method called wrong number of times - Stack Overflow

programmeradmin4浏览0评论

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

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?

Share Improve this question edited Feb 19, 2018 at 19:52 Sree 1,7581 gold badge19 silver badges29 bronze badges asked Feb 19, 2018 at 18:31 Tony TangTony Tang 1031 gold badge1 silver badge5 bronze badges 1
  • 1 always always always have a catch clause in your promise chain. – Evert Commented Feb 19, 2018 at 18:35
Add a ment  | 

2 Answers 2

Reset to default 9

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);
})
发布评论

评论列表(0)

  1. 暂无评论