如何使用JEST测试递归函数的时间过程

2024-02-03

我使用 JEST 编写测试。我不知道如何在 JEST 中测试承诺递归。

在此测试中,执行递归的重试函数是测试的目标,直到 Promise 得到解决。

export function retry<T>(fn: () => Promise<T>, limit: number = 5, interval: number = 1000): Promise<T> {
  return new Promise((resolve, reject) => {
    fn()
      .then(resolve)
      .catch((error) => {
        setTimeout(() => {
          // Reject if the upper limit number of retries is exceeded
          if (limit === 1) {
            reject(error);

            return;
          }
          // Performs recursive processing of callbacks for which the upper limit number of retries has not been completed
          try {
            resolve(retry(fn, limit - 1, interval));
          } catch (err) {
            reject(err);
          }
        }, interval);
      });
  });
}

对上述重试功能进行如下测试。

  1. retry() 在第三次运行时解决。第一次、第二次和第三次分别每 1000 秒调用一次。

当我用 JEST 写这些的时候,我想应该是这样的。


jest.useFakeTimers();

describe('retry', () => {
  // Timer initialization for each test
  beforeEach(() => {
    jest.clearAllTimers();
  });
  // Initialize timer after all tests
  afterEach(() => {
    jest.clearAllTimers();
  });

  test('resolve on the third call', async () => {
    const fn = jest
      .fn()
      .mockRejectedValueOnce(new Error('Async error'))
      .mockRejectedValueOnce(new Error('Async error'))
      .mockResolvedValueOnce('resolve');

    // Test not to be called
    expect(fn).not.toBeCalled();
    // Mock function call firs execution
    await retry(fn);
    // Advance Timer for 1000 ms and execute for the second time
    jest.advanceTimersByTime(1000);
    expect(fn).toHaveBeenCalledTimes(2);
    // Advance Timer for 1000 ms and execute for the third time
    jest.advanceTimersByTime(1000);
    expect(fn).toHaveBeenCalledTimes(3);

    await expect(fn).resolves.toBe('resolve');
  });

});

结果,失败了,出现以下错误。

● retry › resolve on the third call
Timeout - Async callback was not invoked within the 30000ms timeout specified by jest.setTimeout.Error: 

    > 16 |   test('resolve on the third call', async () => {
         |   ^
      17 |     jest.useFakeTimers();
      18 |     const fn = jest
      19 |       .fn()

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


你的函数很难用计时器进行测试。

你打电话时await retry(fn);这意味着您将等到retry返回一个值,但是setTimeout已被阻止,直到您致电为止jest.advanceTimersByTime(1000);=>这是主要原因,因为jest.advanceTimersByTime(1000);从未被叫过。

你可以看我的例子,它与 jest 的假定时器一起工作得很好。

  test("timing", async () => {
    async function simpleTimer(callback) {
      await callback();
      setTimeout(() => {
        simpleTimer(callback);
      }, 1000);
    }

    const callback = jest.fn();
    await simpleTimer(callback); // it does not block any things
    for (let i = 0; i < 8; i++) {
      jest.advanceTimersByTime(1000); // then, this line will be execute
      await Promise.resolve(); // allow any pending jobs in the PromiseJobs queue to run
    }
    expect(callback).toHaveBeenCalledTimes(9);  // SUCCESS
  });

我认为,您可以跳过测试计时器细节,只测试您的逻辑:fn已经调用了3次,终于返回了"resolve"

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

    // expect.assertions(3);

    // Test not to be called
    expect(fn).not.toBeCalled();
    // Mock function call firs execution

    const result = await retry(fn);

    expect(result).toEqual("resolve");

    expect(fn).toHaveBeenCalledTimes(3);
  });

注意:删除所有假计时器 - jest.useFakeTimers

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用JEST测试递归函数的时间过程 的相关文章

  • 使用本地存储在从另一个表保存的 HTML TABLE 中打印 JSON,以便我在另一个页面上打印我的表

    在我的作业中 我必须使用用户输入中的数据并将数据保存在本地存储中 我必须以水平表格式将这些数据从本地存储打印到其他页面 为此 我编写了用于用户输入并将数据保存在本地存储中的代码 div p p div
  • Jquery 悬停卡

    我在用着http designwithpc com Plugins Hovercard http designwithpc com Plugins Hovercard 但我不知道如何在悬停卡上声明 var 每个工作描述都有自己的 ID 当悬
  • 浏览器视口大小(以设备像素为单位)

    Goal 我希望 Flash 能够获得有关浏览器视口宽度和高度 以设备像素为单位 的准确信息初始化 调整大小或浏览器缩放事件时 规格 我需要将 flash 嵌入到在 chrome safari firefox 等中运行的 html 页面中
  • Firebase,只得到新的孩子[重复]

    这个问题在这里已经有答案了 var firebase new Firebase firebaseRef on child added function snapshot 这将接收所有元素 有没有办法在创建新的 Firebase 引用时不接收
  • 从函数返回函数的目的是什么?

    阅读一些遗留代码 发现 A prototype setSize function var v1 new Vector2 return function size var halfSize v1 copy size multiplyScala
  • 使用 Angular 指令禁用文本选择

    我正在学习 JavaScript 和 AngularJS 我想使用 Angular Directive 禁用文本选择 我有该函数的 JavaScript 代码 function clearSelection if document sele
  • 如何使用有角度的材料创建卡片网格?

    我正在尝试使用 ng repeat 创建每行三张卡片的网格 我有一个普通的 javascript 对象数组附加到范围 下面的代码将为每张卡创建一个新行 div div
  • Number.IsNaN() 比 isNaN() 更糟糕吗

    Soooooo isNaNJavaScript 显然被破坏了 比如 isNaN isNaN isNaN true isNaN false isNaN 0 返回 false 当它们看起来都是 不是数字 在 ECMAScript 6 中 草案包
  • 想要动态处理与分页相关的页码显示:ReactJS

    我有一些分页逻辑工作得很好 唯一的问题是我只能让它显示并固定数量的页面可供选择 现在我已经把它放到了 5 页 但我希望它能够根据总记录动态更改 假设我有 100 条记录 每页限制为 10 条 将有 10 页 现在我只能让它以这种方式显示 第
  • 如何使用javascript确保元素仅在圆上朝一个方向移动?

    好吧 我承认我对三角学真的很糟糕 出于上下文的考虑 我将添加我在这里提到的问题中的内容 参考问题 https stackoverflow com a 39429290 168492 https stackoverflow com a 394
  • JavaScript 验证和 PHP 验证?

    我正在使用 jquery 验证插件来验证空表单 我还应该在 PHP 中检查一下以确保 100 正确吗 或者用 javascript 验证就可以了 谢谢 您应该始终在服务器上进行验证 如果用户以某种方式不使用 Javascript 提交表单
  • 通过扩展和实现的组合来理解 TS 的类型推断/缩小

    我有以下示例代码 class B implements Error name string message string stack undefined string function Foo x any if x instanceof E
  • JavaScript 继承;调用和原型

    要在Javascript中实现继承 通常需要执行以下两个步骤 假设我有一个基类 Animal var Animal function name this name name 我现在想从中派生一个子类 Dog 所以我想说 var Dog fu
  • JavaScript 中的 Promise 有什么意义?

    一个承诺是一个 可能现在可用 或将来可用 或永远不可用的值 来源 MDN 假设我有一个想要处理图片的应用程序 图片已加载 例如在算法在后台使用它之后 或某种其他类型的延迟 现在我想检查一下图片是否可以在future 通过使用承诺 而不是回调
  • JavaScript eval("{}") 返回行为?

    根据ECMA 262 规范 http www ecma international org publications files ECMA ST Ecma 262 pdf 以下语句返回1 eval 1 eval 1 eval 1 var a
  • 主页(网格)上的缩略图现在显得模糊。如何纠正?

    我不知道这看起来是否愚蠢 但从早上开始我就无法纠正这个突然出现在我的博客网站上的错误www candidopinions in http www candidopinions in 我有一个网格视图模板 其中博客文章中的特色图像作为调整大小
  • 使用 Enzyme 测试 `React.createRef` api

    我想测试下面的类 它使用React createRef api 不过 快速搜索并没有发现任何这样做的例子 有人成功过吗 我该如何嘲笑裁判 理想情况下我想使用shallow class Main extends React Component
  • 什么是 WKWebView 中的 WKErrorDomain 错误 4

    fatal error LPWebView encounters an error Error Domain WKErrorDomain Code 4 A JavaScript exception occurred UserInfo 0x7
  • 如何通过索引访问 JSON 对象中的字段

    我知道这不是最好的方法 但我别无选择 我必须通过索引访问 JSONObject 中的项目 访问对象的标准方法是只写this objectName or this objectName 我还找到了一种获取 json 对象内所有字段的方法 fo
  • 使用velocity.js制作可拖动元素的动画

    我正在使用velocity js 为用户拖动的可拖动 SVG 元素设置动画 然而 velocity js 将先前的 mousemove 坐标排队并通过所有后续的 mousemove 坐标进行动画处理 我想要的是velocity js 不要对

随机推荐

  • 尝试理解 Ruby 中 self.method_name 与 Classname.method_name 的使用

    我试图了解何时使用 self method name 与何时使用 Classname method name 在下面的示例中 为什么 before create 需要引用 User hash password 而不是 self hash p
  • Apache:如何对用户隐藏服务器版本和操作系统?

    我在一个网站上读到我需要添加两行httpd conf file 服务器签名关闭 ServerTokens 产品 但当我添加它们后 一切都没有改变 正如之前我可以在浏览器中看到的 Apache 2 2 16 Debian 也许这很重要 当我打
  • 默认的 VB6 字符集是什么?

    我们有一个用 Java 编写的应用程序 它读取 VB6 应用程序生成的一些文本 问题是 这个 VB6 应用程序使用一些特殊字符生成此输出 例如 我们不知道这些字符采用什么字符集 那么问题来了 VB6有没有使用默认的字符集 是哪一个 如何将数
  • 如何通过新的 V2 API 使用 Google Translate TTS?

    我曾经使用以下网址调用 Google Translate TTS 下载音频文件 然而谷歌改变了工作方式 因此我无法再下载音频文件 我已注册 Google Translate API V2 免费试用版 但找不到如何获取 TTS 音频文件 任何
  • Android 4.0.3 (MIUI ROM) 下未加载本机库

    一位客户联系我 当他将 Android ROM 更新到相当于 Android 4 0 3 的 MIUI 时 我的 Android 应用程序崩溃了 LogCat 中的相关行是 04 09 10 37 09 326 17789 17789 E
  • 在 OS X Lion 10.7.4 和 Python 3.2.2 上安装 MatPlotLib 1.2.x

    几天前我问了一个关于在同一系统上安装 numpy 的问题 值得庆幸的是 我自己设法解决了这个问题 但不幸的是我现在陷入了尝试安装 matplotlib 的困境 我首先尝试了当前的分布式版本 但没有成功 所以我想我应该下载 git 存储库并尝
  • 函数模板重载解析和编译器优化

    我正在看这里发现的这个问题包含类型的类型的模板函数重载 https stackoverflow com questions 44511121 template function overload for type containing a
  • 将数据存储为 flutter 中共享首选项中的对象

    我想在共享首选项中存储一个对象 其中包含一些字段 如姓名 年龄 电话号码等 我不知道如何在颤振中的共享首选项中存储对象 您可以将对象存储在共享首选项中 如下所示 SharedPreferences shared User await Sha
  • 使用 EDITBIN 时的错误代码 -1073741515

    我正在使用 EditBin 来增加我正在编写的应用程序的堆栈大小 我在 Visual Studio 的构建后事件命令行中包含以下内容 C Program Files x86 Microsoft Visual Studio 10 0 VC b
  • 如何使我的网站符合 PCI 标准

    假设我决定使用支付网关而不是使用他们的托管页面 而是提供我自己的信用卡详细信息表单 然后通过 xml 将数据发送到他们的后端 如下所示本页有解释 http www eway com au Developer eway api hosted
  • Java内存模型:编译器重新排列代码行

    众所周知 Java 语言允许编译器重新排列已编译代码行 只要重新排序对代码语义没有影响即可 然而 编译器只需关心语义 如从当前线程 如果这种重新排序影响多线程情况下的语义 通常会导致并发问题 内存可见性 我的问题 通过允许编译器使用这个 f
  • 如何使用 matplotlib 在圆环饼图中制作子图?

    如何使用Python的matplotlib为圆环饼图制作子图 下面是我写的代码 import matplotlib pyplot as plt labels Frogs Hogs Dogs sizes 15 30 45 colors yel
  • 如何将 Dart Html 客户端 Web 套接字响应从 Blob 转换为 Uint8List?

    我已经实现了自己的二进制消息协议 用于从 Dart 客户端到 Java 服务器的简单请求 响应对象 它们在 Dart 中编码为 Uint8List 在远程服务器上以 Java 编码为 ByteBuffer 往返适用于 dart io 中的
  • 将空格分隔的文件转换为 CSV

    我有一个包含表格数据的文本文件 我需要做的是自动执行写入以逗号分隔而不是空格分隔的新文本文件的任务 从现有数据中提取几列 对列重新排序 这是原始数据前 4 行的片段 Number of rows 8542 Algorithm Date Ti
  • dplyr 掩盖 GGally 并破坏 ggparcoord

    鉴于新的会议 执行一个小ggparcoord 函数文档中提供的示例 library GGally data diamonds package ggplot2 diamonds samp lt diamonds sample 1 dim di
  • 使用 Angular Web 应用程序调用 mongo/golang db 时被 CORS 策略错误阻止

    我正在制作一个前端带有 Angular 的 Web 应用程序 后端带有 golang 和 mongo 的数据库 我已经启动并运行了数据库 并且所有路由请求都已经过测试并且正在 Postman 上运行 但是 当我尝试对 Angular 应用程
  • 如何将 char* 转换为 std::vector?

    我有一个 char 变量 char buffer fread buffer 1 lSize pFile 如何将其转换为 std vector 铸造会给我一个错误 std vector
  • 如何在fragment中保存recyclerview的滚动位置

    我从这里遵循了很多答案 但没有一个解决我的问题 这就是我问的原因 我想在片段中保存滚动位置 在他们建议遵循的许多文章中 Override protected void onSaveInstanceState Bundle outState
  • 无法连接到本地运行时:加载服务器扩展时出错 —

    我正在尝试连接到本地运行时进行编辑Mask R CNN模型 https colab research google com github tensorflow tpu blob master models official mask rcn
  • 如何使用JEST测试递归函数的时间过程

    我使用 JEST 编写测试 我不知道如何在 JEST 中测试承诺递归 在此测试中 执行递归的重试函数是测试的目标 直到 Promise 得到解决 export function retry