在前端开发中,测试是不可或缺的一部分。而 Chai 是一个流行的断言库,用于编写可读性强的测试用例。
Chai 提供了许多内置的 matchers,例如 expect
、assert
和 should
。然而,内置的 matchers 可能无法完全满足我们的测试需求。在这种情况下,我们可以使用自定义 matchers 来扩展 Chai。
这篇文章将演示如何在 Chai 中使用自定义 matchers,并展示自定义 matchers 的实用性。
示例场景
我们假设有一个深度嵌套的对象,我们需要测试该对象的属性是否等于某个值。一种常见的方法是使用 JavaScript 的深度相等运算符 ===
,例如:
-- -------------------- ---- ------- ----- --- - - ---- - ---- - ---- ------- - - -- ------------------------------------------
虽然这个测试能够正常运行,但它有一个问题:如果 obj.foo.bar
不存在,则会抛出一个异常。为了避免这个问题,我们可以使用 Chai 的 nested
方法,例如:
expect(obj).to.have.nested.property("foo.bar.baz", "hello");
但是,如果我们需要在多个测试用例中多次执行类似的测试,这将非常繁琐。为了减少重复代码,我们可以创建一个自定义 matcher。
创建自定义 matcher
Chai 提供了 chai.use
方法,可以让我们使用插件(plugin)中定义的方法。我们可以通过创建一个插件来定义自定义 matcher。
首先,我们需要定义一个函数,该函数将接收 chai
和 utils
作为参数。chai
是一个对象,包含了 Chai 的所有方法和属性,而 utils
是一个对象,包含了一些有用的方法,例如 flag
、transferFlags
等。
function deepEquals(util, customEqualityTesters) { // ... }
接着,我们需要使用 chai.Assertion.addMethod
方法来添加自定义 matcher。该方法需要两个参数:matcher 的名称和一个函数,这个函数将被执行来验证断言。
this
关键字在 Chai 中表示被断言的对象。我们可以通过 this._obj
获取断言对象。如果我们调用自定义 matcher 的 not
语法,this
将包含键名为 negate
的属性。
-- -------------------- ---- ------- -------------------------------------- ------------- - ----- -------- - -------------------- ----- ------ - -------------------------- ----- ---- - -------- --- ------- -- ------ - ------------ ----- --------- ------------ -- --- ---- ----- ------------- --------- ------------ -- ---- ----- ------------ -- - ---- - ------------ ----- --------- ------------ -- --- ---- ----- ------------- --------- ------------ -- ---- ----- ------------- --------- ------- ---- -- ------ ---- ------- -- - ---
在上面的代码中,我们使用 JSON.stringify
将对象转换成字符串来计算期望值和实际值。然后,我们使用断言的方式来验证这两个值是否相等。如果两个值不相等,我们将依次传入不同的参数,以便在测试失败时显示更有用的信息。
现在,我们可以使用自定义 matcher 来执行测试:
expect(obj.foo.bar.baz).to.deepEquals("hello");
运行测试后,我们应该看到类似如下的结果:
AssertionError: expected {"baz":"world"} to deep equal "hello" + expected - actual -"hello" +"{"baz":"world"}"
结论
在本文中,我们演示了如何在 Chai 中使用自定义 matcher。通过编写自定义的 matcher,我们可以使测试用例变得更简洁和可读。
自定义 matcher 可以很容易地扩展 Chai,适应不同的测试需求。无论是在编写单元测试、集成测试还是端到端测试,都可以使用自定义 matcher 消除重复代码,提高测试的可维护性。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/671dad029babaf620fb78a67