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