javascript - 如何用 JEST 测试 promise 递归

标签 javascript typescript jestjs

我使用 JEST 编写了一个测试。 我不知道如何在 JEST 中测试 promise 递归。

在这个测试中,执行递归的重试函数是测试的目标,直到 promise 被解决。

export function retry <T> (fn: () => Promise <T>, limit: number = 5, interval: number = 10): Promise <T> {
  return new Promise ((resolve, reject) => {
    fn ()
      .then (resolve)
      .catch ((error) => {
        setTimeout (async () => {
          // Reject if the upper limit number of retries is exceeded
          if (limit === 1) {
            reject (error);
            return;
          }
          // If it is less than the upper limit number of retries, execute callback processing recursively
          await retry (fn, limit-1, interval);
        }, interval);
      });
  });
}

对上述重试函数进行如下测试。

  1. 总是传递一个 resolve 的 promise,重试函数在第一次执行时被 resolve
  2. 在第三次运行时将resolve传递给resolve,retry函数在第三次运行时解析

我以为用JEST写这些的时候会是这样

describe ('retry', () => {
  test ('resolve on the first call', async () => {
    const fn = jest.fn (). mockResolvedValue ('resolve!');
    await retry (fn);
    expect (fn.mock.calls.length) .toBe (1);
  });

  test ('resolve on the third call', async () => {
    const fn = jest.fn ()
               .mockRejectedValueOnce (new Error ('Async error'))
               .mockRejectedValueOnce (new Error ('Async error'))
               .mockResolvedValue ('OK');
    expect (fn.mock.calls.length) .toBe (3)
  });
});

结果报以下错误失败

Timeout-Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Error:
    > 40 | test ('resolve on the third call', async () => {
         | ^
      41 | const fn = jest
      42 | .fn ()
      43 | .mockRejectedValueOnce (new Error ('Async error'))

关于这个错误,我认为在 JEST 的设置中是可以管理的。但是,从根本上说,我不知道如何在 JEST 中测试 promise 递归处理。

最佳答案

也许您的retry 任务花费了太多次(例如:4,9s),然后您没有足够的时间来做下一个测试用例。

您可以使用 jest.setTimeout(10000);

增加 JEST 的 timeout

Promise testing官方文档。

我对你的案例的解决方案:

test("resolve on the third call", async () => {
    jest.setTimeout(10000);
    const fn = jest.fn()
      .mockRejectedValueOnce(new Error("Async error"))
      .mockRejectedValueOnce(new Error("Async error"))
      .mockResolvedValue("OK");

    // test reject value
    await expect(fn()).rejects.toEqual(new Error("Async error"));
    await expect(fn()).rejects.toEqual(new Error("Async error"));

    // test resolve
    const result = await fn();
    expect(result).toEqual("OK");

    // call time
    expect(fn).toHaveBeenCalledTimes(3);
  });

关于javascript - 如何用 JEST 测试 promise 递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56121290/

相关文章:

typescript - ag-grid cellEditor 选择对象值

reactjs - 在 react native + typescript 应用程序上运行 jest 时出错(Jest 遇到意外 token )

node.js - 开 Jest 无法解析模块别名

javascript - Select2 允许清除不起作用

javascript - 未将数组从 Node.js 获取到 AJAX

node.js - 如何在应用程序或功能模块加载时显式执行某些代码?

typescript - 使用 Typescript 从 Jest 手动模拟导入函数

javascript - 循环中的 SetTimeOut

javascript - 是否可以在现有的纯 Javascript 项目中添加 Angular 组件?

javascript - 访问 firebase 数据库中的数据