核心插件概念
插件不仅仅用于编写供应商集成。作为测试人员,您可以编写插件来验证输入数据,断言对象上的模式验证,或确保DOM元素上的正确行为。API足够灵活,任何同步任务都可以轻松地封装在一个断言中,并在整个测试中重复使用。
本教程将向您展示如何访问Chai的插件API,使用标志通过语言链传递数据,并编写您的第一个断言(以及完整的错误消息)。完成此操作后,构建辅助函数将向您展示如何组合属性和方法以在Chai语言链上使用。
访问实用程序
Chai附带了许多实用程序来帮助构建断言,但它不会直接在chai
导出中提供这些实用程序。可以通过使用chai导出的use
方法访问这些实用程序,该方法接受一个函数作为参数。
chai.use(function (_chai, utils) {
// ...
});
将使用的函数将其范围传递两个参数。第一个是chai
导出,第二个是包含许多实用程序方法的对象(我们将在稍后介绍这些方法)。
包含chai
导出是为了让您构建可以在多个测试文件中使用的辅助函数,或者将您的辅助函数打包为插件以与社区共享。创建辅助函数更合适的模式如下…
对于我们的辅助函数文件:test/helpers/model.js
module.exports = function (chai, utils) {
var Assertion = chai.Assertion;
// your helpers here
};
以及,对于我们的实际测试:test/person.js
var chai = require('chai')
, chaiModel = require('./helpers/model')
, expect = chai.expect;
chai.use(chaiModel);
在本文档的其余部分,我们将假设这种结构…
- 外部文件中的辅助函数
chai.Assertion
分配给Assertion
变量- 所有辅助函数都将在导出函数内,位于指示的位置
现在,Assertion
变量是断言链的构造函数;new Assertion(obj)
现在等效于expect(obj)
。
使用标志
断言内部工作方式的最核心概念是标志的概念。每个断言都有一组与之关联的大多数情况下任意的标志 - 键:值对。Chai在内部使用少量这些标志,但该存储库也供开发人员扩展。
标志用法
标志实用程序在我们的use
函数中作为utils.flag
公开。它可以作为 getter 或 setter,具体取决于传递给它的参数数量。
var myAssert = new Assertion(obj);
utils.flag(myAssert, 'owner', 'me'); // sets key `owner` to `me`
var owner = utils.flag(myAssert, 'owner'); // get key `owner', returns value
对象标志
Chai 保留的标志中最重要的一个是object
标志。这是断言的主题。
var myAssert = new Assertion('Arthur Dent');
var obj = flag(myAssert, 'object'); // obj === 'Arthur Dent';
此标志使用频率如此之高,以至于提供了一个快捷方式作为构造断言的_obj
属性。
var obj = myAssert._obj; // obj === `Arthur Dent`
以下标志由Chai的核心断言使用。如果您干扰这些标志,可能会发生副作用。
object
: (如上所示)ssfi
: 开始堆栈函数 - 用于防止回调堆栈在错误中显示。message
: 使用assert
接口时要包含在错误中的附加信息。negate
: 当.not
包含在链中时设置。deep
: 当.deep
包含在链中时设置。由equal
和property
使用contains
: 当include
或contain
用作属性时设置。更改keys
的行为。lengthOf
: 当length
用作属性时设置。更改above
、below
和within
的行为。
组合断言
在我们开始向语言链添加方法和属性之前,我们应该首先检查如何调用断言,以及失败时预期的行为。
为此,每个构造的Assertion
都有一个名为assert
的方法。它接受许多参数,其行为可能会根据断言是否被否定而改变。
基本断言
首先,我们将再次构造亚瑟,然后我们可以断言他就是他所说的那个人。
var arthur = new Assertion('Arthur Dent');
arthur.assert(
arthur._obj === 'Arthur Dent'
, "expected #{this} to be 'Arthur Dent'"
, "expected #{this} to not be 'Arthur Dent'"
);
Chai 将检查第一个参数;如果它是true
,那么断言通过,但如果它是false
,则断言失败,第一个错误消息将作为chai.AssertionError
的一部分抛出。相反,如果语言链被否定,它将认为false
是通过,true
是失败。第二个错误消息将包含在抛出的错误中。
总而言之,assert
方法接受六个参数
- 一个布尔值(真值测试的结果)
- 如果第一个参数是
false
,则要使用的字符串错误消息 - 如果断言被否定且第一个参数是
true
,则要使用的字符串错误消息 - (可选)预期值
- (可选)实际值,默认为
_obj
- (可选)一个布尔值,指示如果第一个参数是
false
,是否在消息之外显示差异
组合错误消息
如您从上面的示例中看到的那样,Chai 可以接受模板标签来动态组合错误消息。使用时,这些模板标签将被替换为相关对象的字符串化替换。有三个模板标签可用。
#{this}
: 断言的_obj
#{exp}
: 预期值(如果它在assert
中提供)#{act}
: 实际值,默认为_obj
,但可以被assert
中提供的 value 覆盖