在 Jest 中如何 mock 一个内部函数

阅读时长 7 分钟读完

当我们在编写前端代码时,经常需要测试一些函数内部的逻辑,对此,我们可以使用 Jest 这个测试框架。在使用 Jest 进行测试时,有时我们需要 Mock 一个函数或者对象,以便测试我们的代码。

在本文中,我们将学习如何在 Jest 中 Mock 一个内部函数,并且掌握如何处理一些常见的使用场景。以下是详细的指导意义和示例代码。

Mock 一个内部函数

Mock 一个内部函数,在 Jest 中并不是一件难事。我们只需要使用 Jest 提供的一些方法来模拟一个内部函数即可。以下是一个示例,假设我们有一个模块名为 utils.js

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

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

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

在这个模块中,函数 getFormattedDate() 计算当前日期并将其格式化为 ISO 字符串。函数 doSomething() 调用了 getFormattedDate() 来获取当前日期,并在内部使用它来执行一些操作。

接下来,我们需要编写一个测试文件,例如 utils.test.js

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

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

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

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

在测试文件中,我们首先 Mock 了 getFormattedDate 函数,以便在测试期间将其返回值设置为固定值(例如 '2021-01-01')。然后,我们调用 doSomething 函数,并使用 expect 断言来测试它的输出是否符合预期。

处理一些常见的使用场景

在实际编写代码时,有时我们需要 Mock 的函数并不是一个纯函数。这意味着它可能会修改全局状态,或者我们可能需要将其返回值分别模拟。下面是一些示例场景,并提供了解决方案和相关的 Jest API:

Mock 一个函数并返回多个值

假设我们需要 Mock 一个函数,并返回它的每次调用的结果都不一样,可以利用 jest.fn()mockImplementation() 方法来实现:

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

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

在上面的示例中,我们首先使用 jest.fn() 方法创建了一个 Mock 函数 mockFn,然后使用 mockImplementationOnce() 方法来分别设置函数的每次调用返回的值。在第四次调用该函数时,它将返回 undefined。

Mock 一个函数并在调用时使用回调函数

有些函数将回调函数作为参数,例如 setTimeout()。为了 Mock 这类函数并在调用时使用回调函数,我们可以使用 jest.useFakeTimers() 方法来创建一个虚假的定时器。

下面是一个示例,假设我们需要 Mock setTimeout() 函数,并在调用时使用回调函数:

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

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

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

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

在上面的示例中,我们首先使用 jest.useFakeTimers() 方法来创建一个虚假的定时器,然后 Mock 了一个函数 mockFn 并传入了一个回调函数作为参数。我们在回调函数中设置了一个 setTimeout() 来间隔 1 秒后调用回调函数并传入一个值。

在最后一步中,我们使用 jest.advanceTimersByTime(1000) 将虚假的定时器前进 1 秒。这样,回调函数就会被调用,并输出 'value'。

Mock 外部依赖

在实际编写代码时,函数可能会依赖其他的模块或库。为了测试这些函数,我们需要 Mock 这些外部依赖。

假设我们需要 Mock axios 库的 get() 方法,可以创建一个虚假的 axios 对象来模拟这个方法:

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

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

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

在上面的示例中,我们首先 Mock 了 axios 库的 get() 方法,并将返回值设置为 Promise.resolve({ data: 'value' })。然后,我们调用依赖于 axios 的函数 myFunction(),并使用 expect 断言来测试 Mock 的 axios.get() 方法是否被正确调用。

结论

在 Jest 中 Mock 一个内部函数并不困难,我们只需要使用 Jest 提供的一些方法来模拟一个内部函数即可。在本文中,我们还探讨了如何处理一些常见的使用场景,例如 Mock 一个函数并返回多个值、Mock 一个函数并在调用时使用回调函数、Mock 外部依赖等。希望这篇文章能够对你在前端测试中使用 Jest 有所帮助。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67511991050cf9039c1a4d50

纠错
反馈