审核中~
溜忙之道
首页
溜忙手册
offer之道
项目Git
写文章
登录
·
注册
登录
没有账号,去注册
注册
已有账号,去登录
博客
chai学习笔记
南易_站长
阅读量:3574
关注
chai学习笔记
`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`去安装。 ```bash "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` 典型用法 ```js 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](https://link.jianshu.com?t=https://github.com/chaijs/deep-eql)而不是strictly equal (===) ```js 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的影响更大 ```js // 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`的第二个参数实现 ```js 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值 ```js expect({a: 1}).to.have.property('a'); expect({a: 1}).to.have.property('a', 1); ``` 当`.property`与`.deep`一起使用的时候,使用的是[deep-eql](https://link.jianshu.com?t=https://github.com/chaijs/deep-eql)而不是strictly equal (===) ```js 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`一起使用来排除继承的属性 ```js 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`一起使用来验证多层内嵌属性 ```js 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`可以一起使用 ```js 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](https://link.jianshu.com?t=https://github.com/chaijs/deep-eql) ```js 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`一起使用来排除继承的属性 ```js 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是当验证失败时会显示的定制错误消息 ```js expect([1, 2, 3]).to.include(4, 'nooo why fail??'); expect([1, 2, 3], 'nooo why fail??').to.include(4); ``` 当`.include`用作链式属性且与`.members`和`.keys`一起使用时,会去验证目标是不是目标对象的子集。 ```js // 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`数组的成员完全一致。 ```js 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](https://link.jianshu.com?t=https://github.com/chaijs/deep-eql) ```js expect([{a: 1}]).to.have.deep.members([{a: 1}]); //pass expect([{a: 1}]).to.have.members([{a: 1}]); //fail ``` 如果成员的顺序也是验证点,那需要用上`.ordered` ```js 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`会去验证目标是不是目标对象的子集而不要求数组长度一致。 ```js // 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`一起使用。 ```js 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`是自定义的错误消息,在验证出错时输出。 ```js 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`,实际上是全小写的字符串。更多信息请参考[这里](https://link.jianshu.com?t=https://github.com/chaijs/type-detect)。 来看几个列子 ```js 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`支持。 ```js var myObj = { [Symbol.toStringTag]: 'myCustomType' }; expect(myObj).to.be.a('myCustomType').but.not.an('object'); ``` `.a`的通常用在验证前检测目标对象的类型,这样可以避免那些根据目标类型不同而展示出不同行为的方法的不正常使用 ```js expect([1, 2, 3]).to.be.an('array').that.includes(2); expect([]).to.be.an('array').that.is.empty; ``` 第二个参数`msg`是自定义的错误消息,在验证出错时输出。 ```js 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`可以是 * 一个或多个字符串参数 * 一个数组 * 一个对象 ```js 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的时候,只能是分隔的参数 ```js 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](https://link.jianshu.com?t=https://github.com/chaijs/deep-eql) ```js 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`的作用 ```js // 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`可以会进行否定式验证。 ```js 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); ``` 不过这种方法不是特别推荐,验证应该直指具体特定的单一目标行为而不是否定式验证,因为否定式验证只是验证多个无效行为中的一个,并不能保证正确性。 ```js expect(2).to.equal(2); expect(2).to.not.equal(1); ``` 很明显,上面第二种方式不是好的验证方式 #### .throw `.throw([errorLike], [errMsgMatcher], [msg])`用来验证方法是否抛出期待的异常错误。 当没有参数的时候,`.throw`会触发目标方法而验证错误已经抛出 ```js var badFn = function () { throw new TypeError('Illegal salmon!'); }; expect(badFn).to.throw(); ``` 当参数被提供并且是错误构造函数,`.throw`会触发目标方法而验证错误已经抛出一个错误实例 ```js var badFn = function () { throw new TypeError('Illegal salmon!'); }; expect(badFn).to.throw(TypeError); ``` 当参数被提供并且是错误实例,`.throw`会触发目标方法而且验证被抛出的错误实例strictly equality(===)提供的错误实例 ```js var err = new TypeError('Illegal salmon!'); var badFn = function () { throw err; }; expect(badFn).to.throw(err); ``` 当参数被提供并且是字符串,`.throw`会触发目标方法而且验证被抛出的错误消息中包含提供字符串参数 ```js var badFn = function () { throw new TypeError('Illegal salmon!'); }; expect(badFn).to.throw('salmon'); ``` 当参数被提供并且是正则表达式,`.throw`会触发目标方法而且验证被抛出的错误消息中匹配提供的正则表达式。 ```js var badFn = function () { throw new TypeError('Illegal salmon!'); }; expect(badFn).to.throw(/salmon/); ``` 当两个参数被提供,第一个是错误实例或构造函数,第二个是正则表达式或是字符串;`.throw`会触发目标方法,然后像上面描述的那样组合起来工作 ```js 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来进行判断 ```js 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`来证明目标对象是存在。然后一般会推荐验证目标对象为某一个特定的值。 ```js 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。 ```js expect([]).to.be.empty; expect('').to.be.empty; ``` 当目标对象是set或map的时候,`.empty`验证其大小(size属性)是否等于(strictly equal ===)0。 ```js 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`对象。 ```js 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`参数。 ```js 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])`验证目标函数是给定构造函数的实例。 ```js function Cat () { } expect(new Cat()).to.be.an.instanceof(Cat); expect([1, 2]).to.be.an.instanceof(Array); ``` #### .lengthOf `.lengthOf(n[, msg])`验证目标对象的length属性是否等于给定的数值。 ```js expect([1, 2, 3]).to.have.lengthOf(3); expect('foo').to.have.lengthOf(3); ``` `.lengthOf`也可以用于语句链式结构中,和`.above`, `.below`, `.least`, `.most`和`.within`一起使用时,会让这些方法去验证目标对象的length属性。不过,并不推荐这种写法,因为我们应该直接验证期待的具体数值而不是范围。 ```js // 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。这个函数可以是继承的。 ```js function Cat () {} Cat.prototype.meow = function () {}; expect(new Cat()).to.respondTo('meow'); ``` 当目标对象是函数的时候,`.respondTo`验证目标函数的`prototype`属性包含一个名称为参数`method`的函数。这个函数可以是继承的。 ```js function Cat () {} Cat.prototype.meow = function () {}; expect(Cat).to.respondTo('meow'); ``` 在链接结构中加入`.itself`会使得`.respondTo`把目标对象不当成函数来处理,所以是去验证目标对象有一个给定名称的函数而不是去验证目标函数的`prototype`属性包含一个名称为参数`method`的函数,即使传入的目标对象是函数本身。下面例子表明加入`.itself`之后,在`prototype`属性加上的函数meow就不会被验证到。 ```js function Cat () {} Cat.prototype.meow = function () {}; Cat.hiss = function () {}; expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); ``` 在验证方法是否存在之前,我们也可以先验证下目标对象的类型。 ```js function Cat () {} Cat.prototype.meow = function () {}; expect(new Cat()).to.be.an('object').that.respondsTo('meow'); ``` 加上`.not`进行negative的判断 ```js function Dog () {} Dog.prototype.bark = function () {}; expect(new Dog()).to.not.respondTo('meow'); ``` `.respondTo`接受第二个可选参数`msg`来自定义错误消息,也可以加上第二个参数给`expect()`。 ```js expect({}).to.respondTo('meow', 'nooo why fail??'); expect({}, 'nooo why fail??').to.respondTo('meow'); ``` #### .satisfy `.satisfy(matcher[, msg])`的参数`matcher`是一个方法,这个方法会接受目标对象当做第一个参数,并且进行验证且返回true。 下面这个例子中`1`作为目标对象传给了`matcher`方法,进行了判断,返回了true ```js expect(1).to.satisfy(function(num) { return num > 0; }); ``` `.satisfy`接受第二个可选参数`msg`来自定义错误消息,也可以加上第二个参数给`expect()`。 ```js 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`之内。不过不是很推荐这种不精准的验证。 ```js // 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()`。 ```js 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`的一员。 ```js expect(1).to.equal(1); // Recommended expect(1).to.be.oneOf([1, 2, 3]); // Not recommended ``` `.oneOf`接受第三个可选参数`msg`来自定义错误消息,也可以加上第二个参数给`expect()`。 ```js 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`可以验证具体数值。 ```js 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`属性值比目标函数返回的数值大。 ```js 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()`。 ```js 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新的值。 ```js 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新的值。 ```js var frozenObject = Object.freeze({}); expect(frozenObject).to.be.frozen; expect(1).to.be.frozen; ``` #### .finite `.finite`验证目标对象是一个数值并且不是`NaN`和`Infinity`。`expect().to.be.finite` 作者:做测试的DanteYu 链接:https://www.jianshu.com/p/ad59cfd158d4 来源:简书 著作权归作者所有。
评论
表情
发送
10
评论