Chai
是具有BDD/TDD风格的验证库,可以运行在node和浏览器环境中,一般和各类JavaScript框架一起使用。本文主要介绍在node环境中的使用。
为什么说Chai
同时具有BDD或者TDD风格呢?因为Chai
提供了不同风格的接口
-
should
和expect
接口提供了BDD链式风格,是一种更加易读的风格tea.should.have.property('flavors').with.lengthOf(3);
expect(tea).to.have.property('flavors').with.lengthOf(3)
-
assert
提供了更加经典的TDD验证风格assert.lengthOf(tea.flavors, 3);
安装
安装可以使用npm install chai
。更加推荐的做法是在package.json
里面添加chai,然后使用npm install
去安装。
"devDependencies": {
"chai": "*"
}
使用*
可以让每一次执行npm install
的时候都去下载安装Chai
的最新版本,这在持续集成里面能发挥很大的作用。
chai.expect
让我们通过常用方法的实例来看下如何使用chai.expect
。
Chains Getter
下面所有的chains都可以用来增加验证表达式的可读性,读起来更接近自然语言。
- to
- be
- been
- is
- that
- which
- and
- has
- have
- with
- at
- of
- same
- but
- does
.equal
.equal
应该算是验证里面用得最多的方法了,用来验证两个对象是否相等,本质是用了strictly equal (===)。.equal(val[,msg])
接受两个参数,第一个是期望值,第二个值是可选的当验证失败时会返回的错误消息。也可以使用.eq
典型用法
expect(1).to.equal(1);
expect('foo').to.equal('foo');
expect(1).to.equal(2, 'this is error msg');
expect('foo').to.eq('foo');
当.equal
与.deep
一起使用的时候,使用的是deep-eql而不是strictly equal (===)
expect({a: 1}).to.equal({a: 1}); // fail
expect({a: 1}).to.deep.equal({a: 1}); //pass
.eql
.eql(obj[, msg])
验证目标对象与给出的参数obj
deeply equal。效果和.equal
与.deep
一起使用一样,不过.deep.equal
对chain的影响更大
// Target object is deeply (but not strictly) equal to {a: 1}
expect({a: 1}).to.eql({a: 1}).but.not.equal({a: 1});
// Target array is deeply (but not strictly) equal to [1, 2]
expect([1, 2]).to.eql([1, 2]).but.not.equal([1, 2]);
.eql
的自定义错误消息可以通过expect
的第二个参数和.eql
的第二个参数实现
expect({a: 1}).to.eql({b: 2}, 'nooo why fail??');
expect({a: 1}, 'nooo why fail??').to.eql({b: 2});
.eqls
与.eql
作用相同,可交换使用。
.property
.property(name[,val[,msg]])
用来判断对象里面的key是否存在,以及在提供第二个参数val
的情况下验证该key对应的value值
expect({a: 1}).to.have.property('a');
expect({a: 1}).to.have.property('a', 1);
当.property
与.deep
一起使用的时候,使用的是deep-eql而不是strictly equal (===)
expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); //pass
expect({x: {a: 1}}).to.have.property('x', {a: 1}); //fail
.property
可以与.own
一起使用来排除继承的属性
Object.prototype.b = 2;
expect({a: 1}).to.have.own.property('a');
expect({a: 1}).to.have.own.property('a', 1);
expect({a: 1}).to.have.property('b').but.not.own.property('b');
.property
可以与.nested
一起使用来验证多层内嵌属性
expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]');
expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]', 'y');
.deep
& .own
& .nested
可以一起使用
expect({x: {a: 1}}).to.have.deep.own.property('x', {a: 1});
expect({a: {b: [{c: 3}]}}).to.have.deep.nested.property('a.b[0]', {c: 3});
.include
.include(val[,msg])
用来验证某种对象子集的包含关系
当对象是字符串的时候,用来判断参数val
是否是目标字符串的子集 expect('foobar').to.include('foo');
当对象是数组的时候,用来判断参数val
是否是数组的一员 expect([1, 2, 3]).to.include(2);
当对象是字典的时候,用来判断参数val
是否是目标对象的子集 expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2});
当对象是集合的时候,用来判断参数val
是否是集合的一员 expect([1, 2, 3]).to.include(2);
当对象是Map
的时候,用来判断参数val
是某一对象的值 expect(new Map([['a', 1], ['b', 2]])).to.include(2);
一般来讲,因为.include
会根据目标对象类型的不同而表现出不同的行为,我们通常在使用.include
之前都会检查对象类型 expect([1, 2, 3]).to.be.an('array').that.includes(2);
默认情况下,strict (===) equality用来比较数组元素和对象属性,如果在链式结构里面加上.deep
,使用的是deep-eql
expect([{a: 1}]).to.include({a: 1}); \\fail
expect([{a: 1}]).to.deep.include({a: 1}); \\pass
expect({x: {a: 1}}).to.include({x: {a: 1}}); \\fail
expect({x: {a: 1}}).to.deep.include({x: {a: 1}}) \\pass
.include
可以与.own
一起使用来排除继承的属性
Object.prototype.b = 2;
expect({a: 1}).to.own.include({a: 1});
expect({a: 1}).to.include({a: 1}).but.not.own.include({b: 2});
.deep
和.own
可以一起使用 expect({a: {b: 2}}).to.deep.own.include({a: {b: 2}});
.include
可以与.nested
一起使用来验证多层内嵌属性 expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'});
.deep
和.nested
可以一起使用 expect({a: {b: [{c:3}]}}).to.deep.nested.include({'a.b[0]': {c: 3}});
如果.
和[]
是真实的属性名称,可以通过双反斜杠来进行转义expect({'.a': {'[b]': 2}}).to.nested.include({'\\.a.\\[b\\]': 2});
当目标对象是去验证参数val
的key的时候,通常我们最好带上value一起做验证expect({a: 3, b: 4}).to.include({a: 3, b: 4});
.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
一起使用时,会去验证目标是不是目标对象的子集。
// Target object's keys are a superset of ['a', 'b'] but not identical
expect({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 identical
expect([1, 2, 3]).to.include.members([1, 2]);
expect([1, 2, 3]).to.not.have.members([1, 2]);
// Duplicates in the subset are ignored
expect([1, 2, 3]).to.include.members([1, 2, 2, 2]);
.members
.members(set[,msg])
用来验证目标数组是不是和参数set
数组的成员完全一致。
expect([1, 2, 3]).to.have.members([2, 1, 3]);
expect([1, 2, 2]).to.have.members([2, 1, 2]);
由上可知,.members
是完全匹配且忽略数组元素的顺序。
默认情况下,strict (===) equality用来比较数组成员,如果在链式结构里面加上.deep
,使用的是deep-eql
expect([{a: 1}]).to.have.deep.members([{a: 1}]); //pass
expect([{a: 1}]).to.have.members([{a: 1}]); //fail
如果成员的顺序也是验证点,那需要用上.ordered
expect([1, 2, 3]).to.have.ordered.members([2, 1, 3]); //fail
expect([1, 2, 3]).to.have.ordered.members([1, 2, 3]); //pass
expect([1, 2, 3]).to.have.members([2, 1, 3]).but.not.ordered.members([2, 1, 3]); //pass
默认情况下.members
会去验证数组的长度是一致的。加上.include
会去验证目标是不是目标对象的子集而不要求数组长度一致。
// Target array is a superset of [1, 2] but not identical
expect([1, 2, 3]).to.include.members([1, 2]);
expect([1, 2, 3]).to.not.have.members([1, 2]);
// Duplicates in the subset are ignored
expect([1, 2, 3]).to.include.members([1, 2, 2, 2]);
.deep
& .include
& ordered
可以和.members
一起使用。
expect([{a: 1}, {b: 2}, {c: 3}]).to.include.deep.ordered.members([{a: 1}, {b: 2}]); //pass
expect([{a: 1}, {b: 2}, {c: 3}]).to.include.deep.ordered.members([{b: 2}, {c: 3}]); //fail
第二个参数msg
是自定义的错误消息,在验证出错时输出。
expect([1, 2]).to.have.members([1, 2, 3], 'nooo why fail??');
expect([1, 2], 'nooo why fail??').to.have.members([1, 2, 3]);
.a
.a(type[, msg])
用于验证目标对象与给出的对象的类型是否一致。关于目标对象类型也是就是参数type
,实际上是全小写的字符串。更多信息请参考这里。
来看几个列子
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');
通过Symbol.toStringTag
自定义的类型能够被.a
支持。
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;
第二个参数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
作用相同,可交换使用。
.keys
.keys(key1[, key2[, …]])
用于某一个key是否存在于目标对象(object, array, map, set)中。
当目标对象是字典或是数组的时候,参数key
可以是
- 一个或多个字符串参数
- 一个数组
- 一个对象
expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
expect(['x', 'y']).to.have.all.keys(0, 1);
expect({a: 1, b: 2}).to.have.all.keys(['a', 'b']);
expect(['x', 'y']).to.have.all.keys([0, 1]);
expect({a: 1, b: 2}).to.have.all.keys({a: 4, b: 5}); // ignore 4 and 5
expect(['x', 'y']).to.have.all.keys({0: 4, 1: 5}); // ignore 4 and 5
当目标对象是map或set的时候,只能是分隔的参数
expect(new Map([['a', 1], ['b', 2]])).to.have.all.keys('a', 'b');
expect(new Set(['a', 'b'])).to.have.all.keys('a', 'b');
由上所知,.keys
根据目标对象的不同而有不同的处理,所以.a
可以用在.keys
之前来检测目标对象的数据类型。expect({a: 1, b: 2}).to.be.an('object').that.has.all.keys('a', 'b');
默认情况下,strict (===) equality用来比较数组成员,如果在链式结构里面加上.deep
,使用的是deep-eql
expect(new Set([{a: 1}])).to.have.all.deep.keys([{a: 1}]); //pass
expect(new Set([{a: 1}])).to.have.all.keys([{a: 1}]); //fail
当给keys
加上了.not
,通常会使用any
来搭配。.not.any.keys
可以验证到给出的key每一个都不在目标对象中,然而not.any.all
做不到。
比如测试目的是验证c和d都不在目标对象中,然后expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('c', 'd');
能通过因为目标对象并没有have all keys也就是c,d同时存在,在取反就会返回true。使用expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
可以达到目的,能够验证目标对象没有任意其中一个key。
如果在.keys
之前加上.any
就会抵消.include
的作用
// Both assertions are identical
expect({a: 1}).to.include.any.keys('a', 'b');
expect({a: 1}).to.have.any.keys('a', 'b');
自定义的错误消息以expect
第二个参数给出。expect({a: 1}, 'nooo why fail??').to.have.key('b');
.key
与.keys
作用相同,可交换使用。
.any
.any
使得所有.keys
验证只要求目标对象包含至少一个指定的keys。与.all
的作用相反。expect({a: 1, b: 2}).to.have.any.keys('a', 'd');
.all
.all
使得所有.keys
验证只要求目标对象包含所有指定的keys。与.any
的作用相反。expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
这是.keys
默认地匹配方式,可以不显示地加上,但是一般加上的话易读性会更好。
.not
.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);
不过这种方法不是特别推荐,验证应该直指具体特定的单一目标行为而不是否定式验证,因为否定式验证只是验证多个无效行为中的一个,并不能保证正确性。
expect(2).to.equal(2);
expect(2).to.not.equal(1);
很明显,上面第二种方式不是好的验证方式
.throw
.throw([errorLike], [errMsgMatcher], [msg])
用来验证方法是否抛出期待的异常错误。
当没有参数的时候,.throw
会触发目标方法而验证错误已经抛出
var badFn = function () { throw new TypeError('Illegal salmon!'); };
expect(badFn).to.throw();
当参数被提供并且是错误构造函数,.throw
会触发目标方法而验证错误已经抛出一个错误实例
var badFn = function () { throw new TypeError('Illegal salmon!'); };
expect(badFn).to.throw(TypeError);
当参数被提供并且是错误实例,.throw
会触发目标方法而且验证被抛出的错误实例strictly equality(===)提供的错误实例
var err = new TypeError('Illegal salmon!');
var badFn = function () { throw err; };
expect(badFn).to.throw(err);
当参数被提供并且是字符串,.throw
会触发目标方法而且验证被抛出的错误消息中包含提供字符串参数
var badFn = function () { throw new TypeError('Illegal salmon!'); };
expect(badFn).to.throw('salmon');
当参数被提供并且是正则表达式,.throw
会触发目标方法而且验证被抛出的错误消息中匹配提供的正则表达式。
var badFn = function () { throw new TypeError('Illegal salmon!'); };
expect(badFn).to.throw(/salmon/);
当两个参数被提供,第一个是错误实例或构造函数,第二个是正则表达式或是字符串;.throw
会触发目标方法,然后像上面描述的那样组合起来工作
var err = new TypeError('Illegal salmon!');
var badFn = function () { throw err; };
expect(badFn).to.throw(TypeError, 'salmon');
expect(badFn).to.throw(TypeError, /salmon/);
expect(badFn).to.throw(err, 'salmon');
expect(badFn).to.throw(err, /salmon/);
.ok
.ok
用来验证目标对象loosely(==) equal与true相等。通常还是推荐使用strictly(===) equal来进行判断
expect(1).to.equal(1); // Recommended
expect(1).to.be.ok; // Not recommended
expect(true).to.be.true; // Recommended
expect(true).to.be.ok; // Not recommended
expect
的第二个参数可以提供自定义的错误消息。expect(false, 'nooo why fail??').to.be.ok;
.true
.true
用来验证目标对象strictly(===) equal与true相等
expect(true).to.be.true;
expect
的第二个参数可以提供自定义的错误消息。expect(false, 'nooo why fail??').to.be.true;
.false
.false
用来验证目标对象strictly(===) equal与false相等
expect(false).to.be.false;
expect
的第二个参数可以提供自定义的错误消息。expect(true, 'nooo why fail??').to.be.false;
.null
.null
用来验证目标对象strictly(===) equal与null相等
expect(null).to.be.null;
expect
的第二个参数可以提供自定义的错误消息。expect(11, 'nooo why fail??').to.be.null;
.undefined
.undefined
用来验证目标对象strictly(===) equal与undefined相等
expect(undefined).to.be.undefined;
expect
的第二个参数可以提供自定义的错误消息。expect(11, 'nooo why fail??').to.be.null;
.NaN
.NaN
用来验证目标对象strictly(===) equal与NaN相等
expect(NaN).to.be.NaN;
expect
的第二个参数可以提供自定义的错误消息。expect(11, 'nooo why fail??').to.be.NaN;
.exist
.exist
用来验证目标对象不等于strictly (===) equal null
或是undefined
来证明目标对象是存在。然后一般会推荐验证目标对象为某一个特定的值。
expect(1).to.equal(1); // Recommended
expect(1).to.exist; // Not recommended
expect(0).to.equal(0); // Recommended
expect(0).to.exist; // Not recommended
expect
的第二个参数可以提供自定义的错误消息。expect(null, 'nooo why fail??').to.exist;
.empty
当目标对象是字符串或是数组的时候,.empty
验证其长度(length属性)是否等于(strictly equal ===)0。
expect([]).to.be.empty;
expect('').to.be.empty;
当目标对象是set或map的时候,.empty
验证其大小(size属性)是否等于(strictly equal ===)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;
expect
的第二个参数可以提供自定义的错误消息。expect([1, 2, 3], 'nooo why fail??').to.be.empty;
.arguments
.arguments
验证目标对象是一个arguments
对象。
function test () {
expect(arguments).to.be.arguments;
}
test();
expect
的第二个参数可以提供自定义的错误消息。expect({}, 'nooo why fail??').to.be.arguments;
.Arguments
与.arguments
作用相同,可交换使用。
.above
.above(n[, msg])
验证目标对象大于给定的数值或日期。expect(2).to.equal(2);
.gt
, .greaterThan
与.above
作用相同,可交换使用。
.least
.least(n[, msg])
验证目标对象至少是(大于或等于)给定的数值或日期 expect(2).to.be.at.least(1);
, expect(2).to.be.at.least(2);
.below
.below(n[, msg])
验证目标对象小于给定的数值或日期。expect(1).to.be.below(2);
.lt
, .lessThan
与.below
作用相同,可交换使用。
.most
.most(n[, msg])
验证目标对象最多是(小于或等于)给定的数值或日期 expect(1).to.be.at.most(2);
, expect(1).to.be.at.least(1);
.within
.within(start, finish[, msg])
验证目标是某一个闭区间内,也就是大于或等于start
参数,小于或等于finish
参数。
expect(2).to.be.within(1, 3);
expect(2).to.be.within(2, 3);
expect(2).to.be.within(1, 2);
.instanceof
.instanceof(constructor[, msg])
验证目标函数是给定构造函数的实例。
function Cat () { }
expect(new Cat()).to.be.an.instanceof(Cat);
expect([1, 2]).to.be.an.instanceof(Array);
.lengthOf
.lengthOf(n[, msg])
验证目标对象的length属性是否等于给定的数值。
expect([1, 2, 3]).to.have.lengthOf(3);
expect('foo').to.have.lengthOf(3);
.lengthOf
也可以用于语句链式结构中,和.above
, .below
, .least
, .most
和.within
一起使用时,会让这些方法去验证目标对象的length属性。不过,并不推荐这种写法,因为我们应该直接验证期待的具体数值而不是范围。
// Recommended
expect([1, 2, 3]).to.have.lengthOf(3);
// Not recommended
expect([1, 2, 3]).to.have.lengthOf.above(2);
expect([1, 2, 3]).to.have.lengthOf.below(4);
expect([1, 2, 3]).to.have.lengthOf.at.least(3);
expect([1, 2, 3]).to.have.lengthOf.at.most(3);
expect([1, 2, 3]).to.have.lengthOf.within(2,4);
.match
.match(re[, msg])
验证目标函数匹配给定的正则表达式。expect('foobar').to.match(/^foo/);
.string
.string(str[, msg])
验证目标函数包含给定的子字符串str
。expect('foobar').to.have.string('bar');
.respondTo
当目标对象不是函数时,.respondTo(method[, msg])
验证目标对象包含一个给定的函数,这个函数的名字就是参数method
.下面的例子表明了Cat实例中包含了一个函数叫做meow。这个函数可以是继承的。
function Cat () {}
Cat.prototype.meow = function () {};
expect(new Cat()).to.respondTo('meow');
当目标对象是函数的时候,.respondTo
验证目标函数的prototype
属性包含一个名称为参数method
的函数。这个函数可以是继承的。
function Cat () {}
Cat.prototype.meow = function () {};
expect(Cat).to.respondTo('meow');
在链接结构中加入.itself
会使得.respondTo
把目标对象不当成函数来处理,所以是去验证目标对象有一个给定名称的函数而不是去验证目标函数的prototype
属性包含一个名称为参数method
的函数,即使传入的目标对象是函数本身。下面例子表明加入.itself
之后,在prototype
属性加上的函数meow就不会被验证到。
function Cat () {}
Cat.prototype.meow = function () {};
Cat.hiss = function () {};
expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow');
在验证方法是否存在之前,我们也可以先验证下目标对象的类型。
function Cat () {}
Cat.prototype.meow = function () {};
expect(new Cat()).to.be.an('object').that.respondsTo('meow');
加上.not
进行negative的判断
function Dog () {}
Dog.prototype.bark = function () {};
expect(new Dog()).to.not.respondTo('meow');
.respondTo
接受第二个可选参数msg
来自定义错误消息,也可以加上第二个参数给expect()
。
expect({}).to.respondTo('meow', 'nooo why fail??');
expect({}, 'nooo why fail??').to.respondTo('meow');
.satisfy
.satisfy(matcher[, msg])
的参数matcher
是一个方法,这个方法会接受目标对象当做第一个参数,并且进行验证且返回true。
下面这个例子中1
作为目标对象传给了matcher
方法,进行了判断,返回了true
expect(1).to.satisfy(function(num) {
return num > 0;
});
.satisfy
接受第二个可选参数msg
来自定义错误消息,也可以加上第二个参数给expect()
。
expect(1).to.satisfy(function(num) {
return num > 2;
}, 'nooo why fail??');
expect(1, 'nooo why fail??').to.satisfy(function(num) {
return num > 2;
});
.satisfies
与.satisfy
作用相同,可以交换使用。
.closeTo
.closeTo(expected, delta[, msg])
验证目标对象与参数expected
的正负差距在参数delta
之内。不过不是很推荐这种不精准的验证。
// Recommended
expect(1.5).to.equal(1.5);
// Not recommended
expect(1.5).to.be.closeTo(1, 0.5);
expect(1.5).to.be.closeTo(2, 0.5);
expect(1.5).to.be.closeTo(1, 1);
.closeTo
接受第三个可选参数msg
来自定义错误消息,也可以加上第二个参数给expect()
。
expect(1.5).to.be.closeTo(3, 1, 'nooo why fail??');
expect(1.5, 'nooo why fail??').to.be.closeTo(3, 1);
.approximately
与.closeTo
作用相同,可以交换使用。
.oneOf
.oneOf(list[, msg])
验证目标对象是参数数组list
的一员。
expect(1).to.equal(1); // Recommended
expect(1).to.be.oneOf([1, 2, 3]); // Not recommended
.oneOf
接受第三个可选参数msg
来自定义错误消息,也可以加上第二个参数给expect()
。
expect(1).to.be.oneOf([2, 3, 4], 'nooo why fail??');
expect(1, 'nooo why fail??').to.be.oneOf([2, 3, 4]);
.increase
当一个参数subject
被给出的时候,.increase(subject[, prop[, msg]])
验证参数方法subject
返回的值比目标函数返回的数值大。目标函数会先于参数函数调用。使用.by
可以验证具体数值。
var val = 1
, addTwo = function () { val += 2; }
, getVal = function () { return val; };
expect(addTwo).to.increase(getVal).by(2); // Recommended
expect(addTwo).to.increase(getVal); // Not recommended
当两个参数subject
和prop
被给出的时候,.increase(subject[, prop[, msg]])
验证目标对象subject
的prop
属性值比目标函数返回的数值大。
var myObj = {val: 1}
, addTwo = function () { myObj.val += 2; };
expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
expect(addTwo).to.increase(myObj, 'val'); // Not recommended
.increase
接受第三个可选参数msg
来自定义错误消息,也可以加上第二个参数给expect()
。
var myObj = {val: 1}
, noop = function () {};
expect(noop).to.increase(myObj, 'val', 'nooo why fail??');
var val = 1
, noop = function () {}
, getVal = function () { return val; };
expect(noop, 'nooo why fail??').to.increase(getVal);
.increases
和.increase
作用相同,可以交换使用。
.decrease(subject[, prop[, msg]])
作用与.increase
恰好相反。
.extensible
.extensible
验证目标对象可以加入新的属性。expect({a: 1}).to.be.extensible;
.sealed
.sealed
验证目标对象是sealed Object,意思就是不能加入新的属性,已经存在的属性不能被删除或reconfigured,但是已经存在的属性可以被assign新的值。
var sealedObject = Object.seal({});
var frozenObject = Object.freeze({});
expect(sealedObject).to.be.sealed;
expect(frozenObject).to.be.sealed;
expect(1).to.be.sealed;
.frozen
.frozen
验证目标对象被frozen Object,意思就是不能加入新的属性,已经存在的属性不能被删除或reconfigured或被assign新的值。
var frozenObject = Object.freeze({});
expect(frozenObject).to.be.frozen;
expect(1).to.be.frozen;
.finite
.finite
验证目标对象是一个数值并且不是NaN
和Infinity
。expect().to.be.finite