【问题标题】:jest mocking promise method called wrong number of times开玩笑的模拟 promise 方法调用错误的次数
【发布时间】:2018-07-30 01:03:33
【问题描述】:

作为我的 redux 操作的一部分,它会发出几个连续的 api 请求。 apiCall 方法返回一个带有某个值的 Promise,该值被后续的 apiCall 用于发出另一个请求,依此类推。我正在使用 Jest 来测试这些 api 调用。

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

我正在尝试编写测试以确保 apiCall 已被正确调用次数和正确参数。

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

Jest 报告 Expected mock function to have been called three times, but it was called one time.

Jest 测试结果表明

  ● 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.

console.log 显示不同值的事实意味着模拟的返回正确地通过了模拟函数并被调用了 3 次。

可能是什么原因造成的?如何正确测试此功能?

【问题讨论】:

  • always always always 在你的 Promise 链中有一个 catch 子句。

标签: javascript rest typescript promise jestjs


【解决方案1】:

使用 async/await 测试异步代码。在这里阅读更多: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);
      });
    });

【讨论】:

    【解决方案2】:

    Promise 是异步的,所以当您检查模拟实际调用一次时。

    您可以改为这样做。等待所有调用完成并返回一个承诺以指示测试是异步的。

    return serialAPIRequests().then(() => {
        expect(myAPI.apiCall).toHaveBeenCalledTimes(3);
    })
    

    【讨论】:

      猜你喜欢
      • 2019-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-29
      • 1970-01-01
      • 1970-01-01
      • 2018-05-05
      相关资源
      最近更新 更多