使用 Chai 和 Sinon.js 进行 Mock 和 Stub

随着前端应用不断增加,测试变得越来越重要。其中,一个很常见的问题就是如何模拟外部依赖,以便于测试自己的代码。在这种情况下,一种常见的解决方案就是使用 Mock 和 Stub。

在本文中,我们将介绍如何使用 Chai 和 Sinon.js 进行 Mock 和 Stub。Chai 是一个行为驱动开发(BDD)测试框架,支持多种风格的测试用例编写。Sinon.js 则是一个 JavaScript 测试工具库,提供了 Mock、Stub、Spy 等绝大多数测试工具。

Mock 和 Stub 的区别

在使用 Mock 和 Stub 之前,我们需要先了解一下它们的区别。

Mock 用于模拟特定行为的外部依赖,并断言测试中特定的交互是否发生。它通常是在测试时使用,并且会根据测试结果有所变化。

Stub 则是一种在测试过程中替换掉一个函数或方法,并强制其返回预先定义的值或执行预定义的行为。其目的是让测试在被测代码的某个依赖出错时,可以正常运行,避免因为这个依赖出错导致整个测试不通过。

使用 Chai 和 Sinon.js 进行 Mock

下面我们来看一个使用 Chai 和 Sinon.js 进行 Mock 的示例。假设我们有一个异步加载图片的函数 loadImage,它接收一个 URL 并返回一个 Promise 对象。我们需要在测试时模拟这个函数的行为,而不是真的加载图片。

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

首先,我们需要安装 Chai 和 Sinon.js:

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

然后在测试文件中,我们可以这样使用 Mock:

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

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

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

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

在这个测试中,我们首先定义了一个模拟图片对象 img,以及一个模拟 Promise 对象 promise,并使用 sinon.stub() 方法创建了一个新的 Stub 方法 loadImageStub,用于替换掉原始方法中的异步加载逻辑。

我们还使用了 sinon.replace() 方法来替换 window.ImageloadImage 的行为,并使用 sinon.fake() 方法创建一个假的 window.Image 对象。之后,我们调用 loadImage 并断言它的返回值等于预期的 Promise 对象。

使用 Chai 和 Sinon.js 进行 Stub

接下来,我们看一看如何使用 Chai 和 Sinon.js 进行 Stub。假设我们有一个计算两个数字之和的函数 add,并且我们希望在测试中,将其依赖的 ajax 函数替换成一个假的实现,以免影响测试结果。

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

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

我们同样需要先安装 Chai 和 Sinon.js:

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

然后在测试文件中,我们可以这样使用 Stub:

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

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

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

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

在这个测试中,我们使用 sinon.stub() 方法创建一个新的 Stub 方法 stub,用于替换掉原始方法中的 ajax 函数。与 Mock 不同的是,Stub 只需要返回一个预定义的值即可,而不需要执行特定的逻辑。

我们同样使用了 sinon.replace() 方法来替换 window.XMLHttpRequestadd.ajax 的行为,并使用 sinon.fakeXMLHttpRequest 方法创建一个假的 XMLHttpRequest 对象。之后,我们调用 add 并断言它的返回值等于预期的结果。

结论

在使用 Chai 和 Sinon.js 进行 Mock 和 Stub 时,我们需要清楚地了解它们的区别,并选择合适的解决方案。Mock 通常用于模拟复杂逻辑和交互,而 Stub 通常用于替换简单逻辑和外部依赖。

Chai 和 Sinon.js 是非常实用的测试工具库,它们提供了丰富的测试工具,并支持多种测试用例编写风格。通过学习它们的使用,我们可以更好地理解前端测试的核心思想,并提高代码的质量和可测试性。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/670fa3855f55128102664d75