chai學習筆記

Chai是具有BDD/TDD風格的驗證庫,可以運行在node和瀏覽器環境中,一般和各類JavaScript框架一起使用。本文主要介紹在node環境中的使用。

為什么說Chai同時具有BDD或者TDD風格呢?因為Chai提供了不同風格的接口

  • shouldexpect接口提供了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])驗證目標對象與給出的參數objdeeply 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])驗證目標函數包含給定的子字符串strexpect('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

當兩個參數subjectprop被給出的時候,.increase(subject[, prop[, msg]])驗證目標對象subjectprop屬性值比目標函數返回的數值大。

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驗證目標對象是一個數值并且不是NaNInfinityexpect().to.be.finite

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容