介绍
chai 是一个断言库,能够与任何javascript测试框架完满地配对。反对BDD和TDD两种格调的断言模式,具备链性能的BDD款式提供了一种表白性强的语言和易于浏览的款式,而TDD断言款式则提供了更古典的感觉:
- should: BDD格调断言
- expect: BDD格调断言
- assert: TDD格调断言
集体倡议应用expect
,在这里只介绍expect
。
装置
npm install chai
语言链
以下是可链接的获取器,以进步断言的可读性。
- to
- be
- been
- is
- that
- which
- and
- has
- have
- with
- at
- of
- same
- but
- does
- still
.not
否定链中随后的所有断言。
expect(function () {}).to.not.throw();expect({a: 1}).to.not.have.property('b');expect([1, 2]).to.be.an('array').that.does.not.include(3);
通常最好断言是产生了一个预期的输入,而不是断言没有产生有数意外的输入之一。所以.not
否定任何断言,并不意味着您应该这样做。
expect(2).to.equal(2); // Recommendedexpect(2).to.not.equal(1); // Not recommended
.deep
导致链中前面的所有.equal,.include,.members,.keys和.property断言应用深度相等而不是严格 ===
相等。
// Target object deeply (but not strictly) equals `{a: 1}`expect({a: 1}).to.deep.equal({a: 1});expect({a: 1}).to.not.equal({a: 1});// Target array deeply (but not strictly) includes `{a: 1}`expect([{a: 1}]).to.deep.include({a: 1});expect([{a: 1}]).to.not.include({a: 1});// Target object deeply (but not strictly) includes `x: {a: 1}`expect({x: {a: 1}}).to.deep.include({x: {a: 1}});expect({x: {a: 1}}).to.not.include({x: {a: 1}});// Target array deeply (but not strictly) has member `{a: 1}`expect([{a: 1}]).to.have.deep.members([{a: 1}]);expect([{a: 1}]).to.not.have.members([{a: 1}]);// Target set deeply (but not strictly) has key `{a: 1}`expect(new Set([{a: 1}])).to.have.deep.keys([{a: 1}]);expect(new Set([{a: 1}])).to.not.have.keys([{a: 1}]);// Target object deeply (but not strictly) has property `x: {a: 1}`expect({x: {a: 1}}).to.have.deep.property('x', {a: 1});expect({x: {a: 1}}).to.not.have.property('x', {a: 1});
.nested
在链中的所有.property和.include断言中启用点和括号符号。
expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]');expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'});
如果 .
或 []
是理论属性名称的一部分,能够通过在其后面增加两个反斜杠来对其进行本义。
expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]');expect({'.a': {'[b]': 'x'}}).to.nested.include({'\\.a.\\[b\\]': 'x'});
.nested不能与.own联合应用。
.own
导致链中的所有.property和.include断言疏忽继承的属性。
Object.prototype.b = 2;expect({a: 1}).to.have.own.property('a');expect({a: 1}).to.have.property('b');expect({a: 1}).to.not.have.own.property('b');expect({a: 1}).to.own.include({a: 1});expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2});
.own不能与.nested组合。
.ordered
使链中前面的所有.member断言要求成员的程序雷同。
expect([1, 2]).to.have.ordered.members([1, 2]).but.not.have.ordered.members([2, 1]);
当.include和.ordered组合在一起时,排序从两个数组的结尾开始。
expect([1, 2, 3]).to.include.ordered.members([1, 2]) .but.not.include.ordered.members([2, 3]);
.any
使链中的所有.keys断言仅要求指标具备至多一个给定的键。
这与.all相同,后者要求指标具备所有给定的键。
expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
无关何时应用.any或.all的指南,请参见.keys文档。
.all
导致链中前面的所有.keys断言要求指标具备所有给定的键。
这与.any相同,后者仅要求指标具备至多一个给定的键。
expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
请留神,当.all和.any都未在链中的晚期增加时,默认状况下将应用.all。
然而,通常最好还是增加.all,因为它能够进步可读性.
无关何时应用.any或.all的指南,请参见.keys文档。
.a(type[, msg])
- @param { String } type
- @param { String } msg optional
断言指标的类型等于给定的字符串类型。
类型不辨别大小写。
无关类型检测算法的信息.
expect('foo').to.be.a('string');expect({a: 1}).to.be.an('object');expect(null).to.be.a('null');expect(undefined).to.be.an('undefined');expect(new Error).to.be.an('error');expect(Promise.resolve()).to.be.a('promise');expect(new Float32Array).to.be.a('float32array');expect(Symbol()).to.be.a('symbol');
.a
反对通过Symbol.toStringTag设置了自定义类型的对象。
var myObj = { [Symbol.toStringTag]: 'myCustomType'};expect(myObj).to.be.a('myCustomType').but.not.an('object');
通常最好应用.a
查看指标的类型,而后再对同一指标进行断言。
这样,您就能够防止因依据指标类型执行不同操作的任何断言而产生意外行为。
expect([1, 2, 3]).to.be.an('array').that.includes(2);expect([]).to.be.an('array').that.is.empty;
在链的后面增加.not,以取反.a
。
然而,通常最好断言指标是预期的类型,而不是断言它不是许多意外类型之一。
expect('foo').to.be.a('string'); // Recommendedexpect('foo').to.not.be.an('array'); // Not recommended
.a
承受一个可选的msg参数,这是一个自定义谬误音讯,以显示断言失败的工夫。
该音讯也能够作为冀望的第二个参数给出。
expect(1).to.be.a('string', 'nooo why fail??');expect(1, 'nooo why fail??').to.be.a('string');
.a
也能够用作语言链来进步断言的可读性。
expect({b: 2}).to.have.a.property('b');
别名.an
能够与.a
调换应用。
.include(val[, msg])
- @param { Mixed } val
- @param { String } msg optional
当指标是字符串时,.include断言给定的字符串val是指标的子字符串。
expect('foobar').to.include('foo');
当指标是数组时,.include断言给定的val是指标的成员。
expect([1, 2, 3]).to.include(2);
当指标是对象时,.include断言给定对象val的属性是指标属性的子集。
expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2});
当指标是Set或WeakSet时,.include断言给定val是指标的成员。应用SameValueZero相等算法。
expect(new Set([1, 2])).to.include(2);
当指标是Map时,.include断言给定的val是指标的值之一。应用SameValueZero相等算法。
expect(new Map([['a', 1], ['b', 2]])).to.include(2);
因为.include会依据指标的类型执行不同的操作,因而在应用.include之前查看指标的类型很重要。无关测试指标类型的信息,请参阅.a文档。
expect([1, 2, 3]).to.be.an('array').that.includes(2);
默认状况下,应用严格(===)相等性比拟数组成员和对象属性。
在链的后面增加.deep,以改为应用深度相等(不反对WeakSet指标)。
// Target array deeply (but not strictly) includes `{a: 1}`expect([{a: 1}]).to.deep.include({a: 1});expect([{a: 1}]).to.not.include({a: 1});// Target object deeply (but not strictly) includes `x: {a: 1}`expect({x: {a: 1}}).to.deep.include({x: {a: 1}});expect({x: {a: 1}}).to.not.include({x: {a: 1}});
默认状况下,应用对象时会搜寻指标的所有属性。这包含继承和/或不可枚举的属性。在链的后面增加.own能够从搜寻中排除指标的继承属性。
Object.prototype.b = 2;expect({a: 1}).to.own.include({a: 1});expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2});
请留神,始终仅在指标对象中搜寻val本人的可枚举属性。
.deep和.own能够组合应用。
expect({a: {b: 2}}).to.deep.own.include({a: {b: 2}});
在援用嵌套属性时,在链的后面增加.nested以启用点和括号符号。
expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'});
如果 .
或 []
是理论属性名称的一部分,能够通过在其后面增加两个反斜杠来对其进行本义。
expect({'.a': {'[b]': 2}}).to.nested.include({'\\.a.\\[b\\]': 2});
.deep和.nested能够组合应用。
expect({a: {b: [{c: 3}]}}).to.deep.nested.include({'a.b[0]': {c: 3}});
.own和.nested不能合并。
在链的后面增加.not,以对消.include。
expect('foobar').to.not.include('taco');expect([1, 2, 3]).to.not.include(4);
然而,当指标是对象时,否定.include是很危险的。问题在于,它断言指标对象没有val的所有键/值对,但可能有也可能没有,因而产生了不确定的冀望。通常最好先确定冀望的确切输入,而后编写仅承受该准确输入的断言。
当甚至不心愿指标对象具备val键时,通常最好精确地断言。
expect({c: 3}).to.not.have.any.keys('a', 'b'); // Recommendedexpect({c: 3}).to.not.include({a: 1, b: 2}); // Not recommended
当冀望指标对象具备val的键时,通常最好断言每个属性都有其期望值,而不是断言每个属性都没有许多意外值之一。
expect({a: 3, b: 4}).to.include({a: 3, b: 4}); // Recommendedexpect({a: 3, b: 4}).to.not.include({a: 1, b: 2}); // Not recommended
.include承受一个可选的msg参数,这是一个自定义谬误音讯,以显示断言失败的工夫。该音讯也能够作为冀望的第二个参数给出。
expect([1, 2, 3]).to.include(4, 'nooo why fail??');expect([1, 2, 3], 'nooo why fail??').to.include(4);
.include也能够用作语言链,导致链中的所有.members和.keys断言要求指标是预期汇合的超集,而不是同一汇合。请留神,增加.include时,.members会疏忽子集中的反复项。
// Target object's keys are a superset of ['a', 'b'] but not identicalexpect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b');expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b');// Target array is a superset of [1, 2] but not identicalexpect([1, 2, 3]).to.include.members([1, 2]);expect([1, 2, 3]).to.not.have.members([1, 2]);// Duplicates in the subset are ignoredexpect([1, 2, 3]).to.include.members([1, 2, 2, 2]);
请留神,在链中的后面增加.any会导致.keys断言疏忽.include。
// Both assertions are identicalexpect({a: 1}).to.include.any.keys('a', 'b');expect({a: 1}).to.have.any.keys('a', 'b');
别名.includes,.contain和.contains能够与.include调换应用。
.ok
断言指标是实在值(在布尔上下文中认为是实在)。
然而,通常最好断言该指标严格(===)或深等于其预期值。
expect(1).to.equal(1); // Recommendedexpect(1).to.be.ok; // Not recommendedexpect(true).to.be.true; // Recommendedexpect(true).to.be.ok; // Not recommended
在链的后面增加.not即可勾销.ok。
expect(0).to.equal(0); // Recommendedexpect(0).to.not.be.ok; // Not recommendedexpect(false).to.be.false; // Recommendedexpect(false).to.not.be.ok; // Not recommendedexpect(null).to.be.null; // Recommendedexpect(null).to.not.be.ok; // Not recommendedexpect(undefined).to.be.undefined; // Recommendedexpect(undefined).to.not.be.ok; // Not recommended
能够将自定义谬误音讯作为预期的第二个参数。
expect(false, 'nooo why fail??').to.be.ok;
.true
断言指标严格(===)等于true。
expect(true).to.be.true;
在链的后面增加.not即可勾销.true。然而,通常最好断言指标等于其期望值,而不是不等于实在值。
expect(false).to.be.false; // Recommendedexpect(false).to.not.be.true; // Not recommendedexpect(1).to.equal(1); // Recommendedexpect(1).to.not.be.true; // Not recommended
能够将自定义谬误音讯作为预期的第二个参数。
expect(false, 'nooo why fail??').to.be.true;
.false
断言指标严格(===)等于false。
expect(null).to.be.false;
.null
断言指标严格(===)等于null。
expect(null).to.be.null;
.undefined
断言指标严格(===)等于undefined。
expect(undefined).to.be.undefined;
.NaN
断言指标严格(===)等于NaN。
expect(NaN).to.be.NaN;
.exist
断言指标不严格等于(===)null或未定义。然而,通常最好断言指标等于其期望值。
expect(1).to.equal(1); // Recommendedexpect(1).to.exist; // Not recommendedexpect(0).to.equal(0); // Recommendedexpect(0).to.exist; // Not recommended
.empty
当指标是字符串或数组时,.empty断言指标的length属性严格(===)等于0。
expect([]).to.be.empty;expect('').to.be.empty;
当指标是地图或汇合时,.empty断言指标的size属性严格等于0。
expect(new Set()).to.be.empty;expect(new Map()).to.be.empty;
当指标是非性能对象时,.empty断言指标没有任何本人的可枚举属性。具备基于符号的键的属性将从计数中排除。
expect({}).to.be.empty;
因为.empty会依据指标的类型执行不同的操作,因而在应用.empty之前查看指标的类型很重要。无关测试指标类型的信息,请参阅.a文档。
expect([]).to.be.an('array').that.is.empty;
在链的后面增加.not即可勾销.empty。然而,通常最好断言指标蕴含其预期的值数,而不是断言目标值不为空。
expect([1, 2, 3]).to.have.lengthOf(3); // Recommendedexpect([1, 2, 3]).to.not.be.empty; // Not recommendedexpect(new Set([1, 2, 3])).to.have.property('size', 3); // Recommendedexpect(new Set([1, 2, 3])).to.not.be.empty; // Not recommendedexpect(Object.keys({a: 1})).to.have.lengthOf(1); // Recommendedexpect({a: 1}).to.not.be.empty; // Not recommended