Chai 中文文档 下载 App

Chai 语言链完整列表 - to be been is that which and has have with 等修饰词

什么是语言链

语言链(Language Chains)是 Chai 里一组可链式访问的 getter 属性。它们不执行任何断言,纯粹提升表达式的可读性。

// 以下两条断言功能完全相同
expect('hello').to.be.a('string');
expect('hello').a('string');  // 省略所有语言链

语言链让断言读起来像一句自然语言。虽然删掉也能跑,但强烈建议保留——代码首先是写给人读的。

完整列表(17 个)

语言链示例备注
toexpect(x).to.equal(y)最常用的连接词
beexpect(x).to.be.a('number')配合 a/an/exist/null 等
beenexpect(x).to.have.been.called配合 sinon spy 使用
isexpect(x).is.a('string')与 be 同义
thatexpect(arr).to.be.an('array').that.includes(1)引导子断言
which同 that引导子断言
andexpect(x).to.be.a('string').and.include('hi')连接两个断言
hasexpect(x).has.property('name')配合 property / lengthOf
have同 has配合 property / lengthOf
withexpect(x).to.have.property('name').with.lengthOf(3)嵌套属性的子链
atexpect(x).to.be.above(100)配合数值比较
ofexpect(arr).to.have.lengthOf(3)lengthOf / members 的一部分
sameexpect(a).to.equal(b)较少单独使用
but同 and连接两个有对比关系的断言
doesexpect(obj).does.not.have.property('name')配合 not 使用
stillexpect(x).to.still.equal(y)语义无区别
also同 and连接并列断言

分组理解

可以按语义把语言链分成四类:

连接类(最常用)

expect(foo).to.be.a('string');
//          ↑   ↑  ↑
//         to  be  a —— 全部是连接类

所属类

expect(config).to.have.property('name');
//            ↑     ↑
//           have  property 是实际断言,have 是所属类

位置类

其他

语言链可以任意组合

只要组合出来的表达式读起来通顺就行,没有语法限制:

expect('hello').to.be.a('string').that.includes('ell').and.has.lengthOf(5);
expect([1, 2, 3]).has.lengthOf(3).which.includes(2);
expect({ a: 1 }).to.have.property('a').which.is.a('number').and.equal(1);

语言链 + 修饰器的组合

语言链经常和真正起作用的修饰器(.not、.deep、.any、.all)混在一起:

expect({ a: { b: 1 } }).to.have.deep.property('a.b');
//                     ↑   ↑    ↑        ↑
//                     语言链 修饰器  语言链  实际断言(property)

修饰器的位置会影响行为——修饰器之后的断言受它影响,之前的不受。详见 .not 否定 和 .deep 修饰器。

语言链不是方法

重要:语言链是属性访问器,不是方法,所以不要加括号:

// ❌ 错误用法
expect(foo).to().be().a('string');

// ✅ 正确
expect(foo).to.be.a('string');

这个区别很关键——如果加了括号,就等于在调用 undefined,会 TypeError。

如果觉得语言链太多

实际项目中常用的语言链只有 to、be、a/an、have、and、that 这几个。其他的偶尔用到也行,用不到不用硬塞。

团队可以约定只保留最自然的表达,避免出现 expect(foo).to.of.be.also.equal(bar) 这种刻意堆砌链的写法。

下一步