Jest mock 的正确姿势,及如何避免一些常见问题

Jest 是一个流行的 JavaScript 测试框架,可用于测试前端和后端应用程序。其中 mock 是 Jest 的一个重要功能,可以用来模拟函数和对象的行为,从而让测试更加可靠和有复现性。本文将介绍 Jest mock 的正确使用方式,并帮助读者避免一些常见问题。

Jest mock 的基本用法

在 Jest 中,有两种方式可以进行 mock:手动 mock 和自动 mock。手动 mock 是指通过 jest.fn() 创建一个模拟函数,然后在测试中用它替换实际函数。自动 mock 是指在测试运行时,Jest 会自动创建模拟对象,让我们可以模拟模块导出的对象或函数。

手动 mock

手动 mock 的使用方式非常简单,只需要在测试文件中创建一个和实际函数同名的 mock 函数,然后将其替换实际函数即可。

-- -------
-------- ------ -- -
  ------ - - --
-

-------------- - - --- --

-- ------------
----- ---- - ------------------

--------- --- --------- -- -- -
  ----- ------- - ----------- -- -- - - ---
  -------- - --------

  ------------------ ------------
  --------------------------------------- ---
---

上面的例子中,我们手动创建了一个名为 addMock 的模拟函数,将其赋值给了 file 模块的 add 属性。在测试中,我们调用 file.add(1, 2),实际上调用的是这个模拟函数。通过 expect(addMock).toHaveBeenCalledWith(1, 2) 可以确认这个 mock 函数被正确调用。

自动 mock

自动 mock 的使用方式更加简便,只需要在测试文件中调用 jest.mock() 方法,并传入要 mock 的模块的路径即可。Jest 会自动创建一个模拟对象,模拟模块导出的对象或函数。

-- -------
-------- ------ -- -
  ------ - - --
-

-------------- - - --- --

-- ------------
----- ---- - ------------------

--------------------

--------- --- --------- -- -- -
  ----------------------------

  ------------------ ------------
  ---------------------------------------- ---
---

上面的例子中,我们直接调用了 jest.mock('./file'),Jest 会自动创建模拟对象,模拟模块导出的对象或函数。在测试中,我们使用 mockReturnValue() 方法设置模拟函数的返回值,然后通过 expect(file.add).toHaveBeenCalledWith(1, 2) 进行验证。注意,使用自动 mock 时,我们需要通过模拟对象的属性或方法来访问被 mocked 的对象或函数。

Jest mock 的高级用法

虽然 Jest mock 的基本用法已经足够简单和实用了,但有时我们需要更加复杂的 mock 行为。在这种情况下,我们需要使用 Jest mock 的高级用法。

模拟同名导出

有些模块导出的对象中包含多个同名属性或方法,我们希望能够对其中特定的属性或方法进行 mock。这时我们可以使用 jest.mock() 方法的第二个参数,传入一个函数来返回模拟对象。

-- -------
-------------- - -
  ------ -- -
    ------ - - --
  --
  ------ -- -
    ------ - - --
  -
--

-- ------------
----- ---- - ------------------

------------------- -- -- --
  ----------- -----
  --------------------------------
  ---- ----------- -- -- - - --
----

---------- ------ ----- -------- -- -- -
  ------------------ ------------
  ------------------ ------------
---

在上面的例子中,我们只 mock 了文件的 add 方法。这里注意,我们需要保留原来的模块导出,否则其他导出的方法都将被 mock 掉。

模拟私有方法

有时我们需要 mock 一个模块中的私有方法,但是无法直接访问它。这时我们可以使用 jest.spyOn() 方法来模拟私有方法的行为。

-- -------
-------- ------ -- -
  ------ - - --
-

-------- -------------- -- -
  ------ - - --
-

-------------- - - --- --

-- ------------
----- ---- - ------------------

---------- ------- ---------- -- -- -
  ----- -------------- - ---------------- ---------------
  ------------------------------------- -- -- - - ---

  ------------------ ------------
  ---------------------------------------------- ---
---

在上面的例子中,我们使用 jest.spyOn() 方法模拟了私有函数 privateFunc 的行为,并通过 mockImplementation() 方法实现模拟逻辑。注意,我们需要在测试结束后恢复原始函数,否则可能会影响其他测试用例。

异步 mock

有些函数是异步的,它们可能会使用回调、Promise 或 async/await 进行异步操作。对于这种情况,我们需要使用 Jest mock 的异步用法。在 Jest 中,我们可以使用 jest.fn()、mockReturnValue()、mockResolvedValue()、mockRejectedValue() 和 mockImplementation() 等方法来实现异步 mock。

-- -------
-------- ------------------- -
  ------------- -- -
    -----------------
  -- ------
-

-------------- - - --------- --

-- ------------
----- ---- - ------------------

---------- ----- ---------- ----- -- -- -
  ----- ------------ - ---------------- -------------
  ------------------------------------------ -- -
    ------------- -- -
      ---------------- -------
    -- ------
  ---

  ----- ---- - ----- --- ----------------- -- -
    --------------------- -- -
      --------------
    ---
  ---

  ------------------------- -------
---

在上面的例子中,我们使用 jest.spyOn() 方法模拟了异步函数 fetchData 的行为,并通过 mockImplementation() 方法实现异步 mock。我们使用 Promise 和 async/await 封装了 fetchData 的回调函数,然后等待 Promise 的结果,并验证返回值是否正确。需要注意的是,我们在测试结束后,需要恢复原始函数。

避免常见问题

在使用 Jest mock 时,有一些常见问题需要避免。下面列出了几个需要注意的事项。

不要误用 jest.requireActual()

jest.requireActual() 是获取真实模块导出的方法,而不是返回 mock 模块的方法。请不要误用它,否则可能会影响测试结果。

不要真正修改原始文件

在使用手动 mock 或 Jest mock 的高级用法时,请不要真正修改原始文件,否则可能会导致测试失败或者其他对象出现问题。

不要在一个测试用例中进行全局修改

在测试用例中,不要全局修改一个对象或变量,否则可能会影响测试结果。

总结

本文介绍了 Jest mock 的基本用法、高级用法以及避免常见问题的方法。Jest mock 是前端测试中必不可少的一个功能,使用正确的方式可以让我们更加轻松地编写可靠和具有复现性的测试用例。希望本文对读者们有所帮助。

来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/65a2570cadd4f0e0ffa769da


猜你喜欢

  • 根据 TypeScript 编写干净,可扩展的代码的建议

    TypeScript 简介 TypeScript 是一种开源的编程语言,它是 JavaScript 的一个严格的超集,可以编译成普通的 JavaScript 代码。

    9 个月前
  • 在 Deno 中如何使用 MongoDB 进行数据持久化?

    在现代化的网络应用程序中,数据持久化是不可少的一个组成部分,尤其是全栈开发。过去在 Node.js 中,我们可以使用 Mongoose 来处理 MongoDB 数据库。

    9 个月前
  • ECMAScript 2018(ES9)中的异步 i/o 和 Promise 机制

    自从ES6中引入Promise之后,异步编程就变得更加容易和直观了。ES9正式将其纳入对一系列新特性的支持之中,这些新特性将有助于更好应对异步I/O等挑战。本文将着重讨论ES9中的异步I/O和Prom...

    9 个月前
  • 如何在 Web Components 中使用 JavaScript 的 Map 对象来存储和检索数据

    Web 组件是现代 Web 开发中的一个重要概念,它能够帮助开发者高效地构建可重用、可维护和可扩展的 Web 应用。为了更好地管理数据,我们可以使用 JavaScript 中的 Map 对象来存储和检...

    9 个月前
  • LESS 中的嵌套 (Mixins) 是什么?

    LESS 中的嵌套 (Mixins) 是什么? LESS 是一种 CSS 预处理器语言,它为开发者提供了许多方便的功能来编写易于维护的 CSS 代码。其中之一就是 LESS 的嵌套 (Mixins)。

    9 个月前
  • 响应式设计中如何用 @media 适配不同的显示器

    响应式设计中如何用 @media 适配不同的显示器 随着数字化信息的快速发展,人们的生活方式也在不断变化,人们的使用设备也千奇百怪。比如,有些人使用手机,有些人使用平板电脑以及笔记本电脑等。

    9 个月前
  • Redis 如何应对内存溢出

    Redis 是一个开源的、高效的、非关系型的数据结构存储系统,特别适用于数据表现形式很少但需要快速访问的应用场景。但是由于 Redis 是一个纯内存数据库,如果使用不当就有可能发生内存溢出现象,这将导...

    9 个月前
  • CSS Reset 的正确应用方式及注意事项

    什么是 CSS Reset CSS Reset 是一种 CSS 样式表的解决方案,它的主要作用是将浏览器默认样式归零,从而消除不同浏览器之间的差异。使用 CSS Reset 可以让页面呈现出更加一致的...

    9 个月前
  • Vue.js 中获取浏览器 URL 参数的方法详解

    在 Vue.js 应用中,获取浏览器 URL 参数是一个非常常见的需求,例如可以根据 URL 参数显示不同的视图或获取特定数据。在本文中,我们将详细介绍如何在 Vue.js 中获取浏览器 URL 参数...

    9 个月前
  • 如何使用 Node.js 发送 HTTP 请求

    在前端开发中,我们常常需要向服务器发起 HTTP 请求来获取数据或者更新数据。而 Node.js 作为一个基于 JavaScript 的运行时环境,可以帮助我们轻松地实现这样的功能。

    9 个月前
  • Promise 在后端出现,你需要掌握它

    Promise 在后端出现,你需要掌握它 随着 Node.js 的流行,Promise 成为了 JavaScript 开发中的必备技能之一。Promise 是一种处理异步操作的方式,它提供了一种处理异...

    9 个月前
  • 通过 Service Worker 实现 PWA 离线访问的步骤详解

    Progressive Web App(PWA)是一种新兴的网页应用程序,它具有类似原生应用程序的用户体验和功能,同时拥有网页应用程序的灵活性和可访问性。其中,实现离线访问是 PWA 非常重要的一个特...

    9 个月前
  • Chai-Http 库的使用方法和示例

    Chai-Http 是一个基于 Chai 断言库的 Node.js HTTP 测试库,它可以帮助开发者编写清晰简洁、可维护、可重用的测试套件。本文将介绍 Chai-Http 库的使用方法和示例,涵盖了...

    9 个月前
  • 利用 Custom Elements 和 Shadow DOM 创建 Modal 组件的正确姿势

    前言 随着 Web 应用的发展,我们经常会使用到一些弹窗组件来增加用户交互体验。目前市面上有很多成熟的弹窗组件库,例如 bootstrap、element-ui 等,它们都提供了相应的弹窗组件。

    9 个月前
  • 如何在 Headless CMS 中管理表单数据

    随着互联网技术的不断发展,前端技术已成为互联网时代的核心技能之一。而 Headless CMS 技术作为一种新兴的内容管理方法,也越来越得到了前端开发者们的关注。在 Headless CMS 中管理表...

    9 个月前
  • MongoDB 中 Capped Collection 使用方法详解

    简介 MongoDB 是一款非常受欢迎的 NoSql 数据库,它的灵活性和高可用性使得它的使用非常广泛。其中有一种集合类型叫做 Capped Collection,也称作固定大小集合。

    9 个月前
  • Koa 实现文件上传

    Koa 是一个 Node.js 的 Web 框架,采用了异步处理流程,基于 Promise 实现的中间件机制,拥有轻量、简洁、灵活等优点,并且其独特的 Error Handling 机制更方便了处理错...

    9 个月前
  • CSS Grid 实现栅格系统的方式与应用案例介绍

    背景 栅格系统是前端开发中常用的一种布局方式,可以让网页更加美观和易读。传统的栅格系统是基于浮动和定位实现的,有很多缺陷和局限性。CSS Grid 是 CSS 中的一种新布局方式,可以更为灵活、高效地...

    9 个月前
  • Fastify 中如何使用 Swagger UI 来展示 API 文档

    Fastify 是一个高效、低开销且高度可定制的 Node.js Web 框架。和其他框架比起来,Fastify 有着更好的性能和稳定性表现。而 Swagger UI 是一个流行的,使用 OpenAP...

    9 个月前
  • Material Design 中 CoordinatorLayout 概述及实现方式详解

    前言 Material Design 是 Google 推出的一种全新的设计语言,旨在为移动端和 Web 应用程序带来一致性的设计风格和用户体验。其中 CoordinatorLayout 是 Mate...

    9 个月前

相关推荐

    暂无文章