如何在 Chai 中使用自定义 matchers 进行深度拓展

阅读时长 4 分钟读完

在前端开发中,测试是不可或缺的一部分。而 Chai 是一个流行的断言库,用于编写可读性强的测试用例。

Chai 提供了许多内置的 matchers,例如 expectassertshould。然而,内置的 matchers 可能无法完全满足我们的测试需求。在这种情况下,我们可以使用自定义 matchers 来扩展 Chai。

这篇文章将演示如何在 Chai 中使用自定义 matchers,并展示自定义 matchers 的实用性。

示例场景

我们假设有一个深度嵌套的对象,我们需要测试该对象的属性是否等于某个值。一种常见的方法是使用 JavaScript 的深度相等运算符 ===,例如:

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

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

虽然这个测试能够正常运行,但它有一个问题:如果 obj.foo.bar 不存在,则会抛出一个异常。为了避免这个问题,我们可以使用 Chai 的 nested 方法,例如:

但是,如果我们需要在多个测试用例中多次执行类似的测试,这将非常繁琐。为了减少重复代码,我们可以创建一个自定义 matcher。

创建自定义 matcher

Chai 提供了 chai.use 方法,可以让我们使用插件(plugin)中定义的方法。我们可以通过创建一个插件来定义自定义 matcher。

首先,我们需要定义一个函数,该函数将接收 chaiutils 作为参数。chai 是一个对象,包含了 Chai 的所有方法和属性,而 utils 是一个对象,包含了一些有用的方法,例如 flagtransferFlags 等。

接着,我们需要使用 chai.Assertion.addMethod 方法来添加自定义 matcher。该方法需要两个参数:matcher 的名称和一个函数,这个函数将被执行来验证断言。

this 关键字在 Chai 中表示被断言的对象。我们可以通过 this._obj 获取断言对象。如果我们调用自定义 matcher 的 not 语法,this 将包含键名为 negate 的属性。

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

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

在上面的代码中,我们使用 JSON.stringify 将对象转换成字符串来计算期望值和实际值。然后,我们使用断言的方式来验证这两个值是否相等。如果两个值不相等,我们将依次传入不同的参数,以便在测试失败时显示更有用的信息。

现在,我们可以使用自定义 matcher 来执行测试:

运行测试后,我们应该看到类似如下的结果:

结论

在本文中,我们演示了如何在 Chai 中使用自定义 matcher。通过编写自定义的 matcher,我们可以使测试用例变得更简洁和可读。

自定义 matcher 可以很容易地扩展 Chai,适应不同的测试需求。无论是在编写单元测试、集成测试还是端到端测试,都可以使用自定义 matcher 消除重复代码,提高测试的可维护性。

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

纠错
反馈