乐趣区

关于javascript:chaijs中文文档

原文档地址:https://www.chaijs.com/api/bdd/


BDD格调蕴含 expect 和 should。它们以雷同的链式构造进行断言,它们的不同之处在于初始的断言结构。能够查看格调指南来进行比拟。


** 译注:格调指南中相干的翻译如下:
(鉴于有代码所以没有放入援用格局而是用分割线与注释辨别)**
BDD 格调有两种格调:expect 和 should。两者都应用雷同的可链接语言来结构断言,但它们在最后结构断言的形式上有所不同。在应用 should 的状况下将可能会产生一些问题,这也有一些形式去克服这些问题。
Expect:BDD 格调裸露 expect 或 should 接口。在这两种状况下,你能够用自然语言的模式来链接断言。Expect 也容许你在任何可能产生的断言失败之前增加任意信息。当与布尔值、数字等非描述性主题一起连用时,这将非常好用。
Should:Should 容许你应用与 Expect 接口雷同的链式断言格调,然而当 should 格调启动链式断言时将可能在 IE 浏览器下存在一些问题,因而要留神浏览器兼容性。
两者间的区别:
首先要留神的是,expect 的引入仅须要引入 expect 函数,而 should 的引入须要引入 should 的函数执行。

var chai = require('chai')
  , expect = chai.expect
  , should = chai.should();

expect 接口提供了一个函数作为链接语言断言的终点。它实用于 node.js 和所有浏览器。
should 接口实例化对象原型的产生繁多实例来进行断言。它实用于 node.js 以及除 Internet Explorer 之外的所有古代浏览器。
Should 须要额定留神的:
should 通过实例化对象的原型进行工作,所以在一些状况下他将可能不会工作


API 参照:

链式语言构造
应用以下的链式供应(getter)来进步你断言的可浏览性啊。

译注:以下的链式构造语句单纯是为了进步浏览性所加的一些天然语句。实际上是没有作用的。后续的 api 才是断言所用的接口。

Chains

  • 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); // 举荐的形式
expect(2).to.not.equal(1); // 不举荐的形式

.deep
将.equal, .include, .members, .keys 和 .property 放在.deep 链式之后将导致应用深度相等的形式来代替严格相等(===)

// 指标对象深度(但不严格) 等于 `{a: 1}`
expect({a: 1}).to.deep.equal({a: 1});
expect({a: 1}).to.not.equal({a: 1});

// 指标数组深度(但不严格) 蕴含 `{a: 1}`
expect([{a: 1}]).to.deep.include({a: 1});
expect([{a: 1}]).to.not.include({a: 1});

// 指标对象深度(但不严格) 蕴含 `x: {a: 1}`
expect({x: {a: 1}}).to.deep.include({x: {a: 1}});
expect({x: {a: 1}}).to.not.include({x: {a: 1}});

// 指标对象深度(但不严格) 含有成员 `{a: 1}`
expect([{a: 1}]).to.have.deep.members([{a: 1}]);
expect([{a: 1}]).to.not.have.members([{a: 1}]);

// 指标 Set 集深度(但不严格) 领有键 `{a: 1}`
expect(new Set([{a: 1}])).to.have.deep.keys([{a: 1}]);
expect(new Set([{a: 1}])).to.not.have.keys([{a: 1}]);

// 指标对象深度(但不严格) 领有属性 `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
使得其后的.members 断言需要以雷同(译注:不加 ordered 时 member 断言值断言成员存在性而漠视程序)的程序断言其成员

expect([1, 2]).to.have.ordered.members([1, 2])
  .but.not.have.ordered.members([2, 1]);

当独特应用.include 和.orderd 时,排序开始于数组的首部。

expect([1, 2]).to.have.ordered.members([1, 2])
  .but.not.have.ordered.members([2, 1]);

.any
使得跟在其后的.key 断言仅需要指标蕴含至多一个所给定的键名,它与需要指标满足所有所给键的.all 断言是相同的。

expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');

.all
使得跟在其后的.key 断言仅需要指标须要蕴含所有所给的键名,它与仅需要指标蕴含至多一个所给定的键名.any 断言是相同的。

expect({a: 1, b: 2}).to.have.all.keys('a', 'b');

须要留神的是当 all 和 any 都没有在链式之前增加的时候是默认应用 all 断言的,然而最好的形式通常是显式的加上 all 以进步断言的可读性。

.lengthOf(n[, msg]):
断言指标的 length 或 size 与给定值雷同,承受参数 msg 在断言谬误时给出提醒。其也能够与.above、.below、.most、.lease、.within 等断言连用。因为兼容性问题,lengthOf 的别名 length 不能间接链接到未经经申明的办法如.a,,因而两者不可调换,应该用 lengthOf 来代替 length。

.lengthOf 承受当断言失败时的客户谬误提醒参数 msg
该参数也能够作为 expect 的第二个参数给出。

expect([1, 2, 3]).to.have.lengthOf(2, 'nooo why fail??');
expect([1, 2, 3], 'nooo why fail??').to.have.lengthOf(2);

译注:当 api 中含有可选参数 [msg] 时均指当断言失败时的客户谬误提醒参数 msg。此时当该断言呈现失败时用户提示信息能够用以下两种模式给出。
expect(target).somechain.somechain.(val, [msg]);
expect(target, [msg]).somechain.somechain.(val);
后续 api 中会屡次呈现 [msg] 均为可在此处传入错误信息的含意。如果该 api 参数中不蕴含 [msg] 参数,则阐明其仅承受错误信息参数作为 expect 的第二个参数被给出。

.match(re[, msg]):
断言指标与给定的正则规定相匹配。

.string(str[, msg]):
断言指标字符串蕴含所给子串,反对 message 在出错时给出用户信息。

.keys(key1[, key2[, …]]):
断言指标对象、数组、map 集、set 集蕴含所给键,只有指标的本身属性在所搜寻范畴内。当指标是一个对象或者一个数组时,键能够以一个或者多个字符串参数的模式提供,也能够是一个繁多的数组参数或这一个独自的对象参数,当是后一种状况(独自的对象参数)时,仅思考给定对象的键素材,而疏忽它的值。当指标是一个 set 或者 map 时,每一个键都必须以参数分隔的模式提供。因为.key 基于不同指标类型做了不同的事,所以在应用.key 之前进行类型检测是十分重要的。
默认状况下,应用严格相等的形式比拟 set 和 map 键,在链式中较早增加.deep 能够应用深度相等的形式去替换它。
默认状况下指标必须含有所有给出的键,能够在链式之前退出.any 使得指标仅需蕴含至多一个给出的键。须要留神的是当.all 和.any 都没有增加的时候默认是应用.all 的,然而举荐显示的应用.all 来进步浏览性。
当.include 和.any 连用的时候,仅.any 失效

// 以下的两种断言是不同的
expect({a: 1}).to.have.any.keys('a', 'b’);
expect({a: 1}).to.include.any.keys('a', 'b');

其错误信息仅能够作为 expect 的第二个参数被给出。

.throw([errorLike], [errMsgMatcher], [msg])
当没有提供参数时,.throw 调用指标函数并断言有一个谬误将被抛出。当有一个参数被提供,并且该参数是一个谬误结构器,.throw 调用指标函数并断言有一个谬误被抛出,该谬误是所给结构器的一个实例。
当仅提供一个参数,且该参数是一个谬误实例时,.throw 调用指标函数并断言其产生一个与给定谬误实例严格相等的谬误。
当仅提供一个字符串参数时,.throw 调用指标函数并断言其产生一个蕴含给定字符串信息的谬误。
当仅提供一个正则表达式参数时,.throw 调用指标函数并断言其产生一个合乎所给正则表达式信息的谬误。
留神一些常见的谬误:
留神传入函数由.throw 进行调用,而不是本人调用

expect(fn).to.throw(); // Good! Tests `fn` as desired
expect(fn()).to.throw(); // Bad! Tests result of `fn()`, not `fn`

另一个常见问题是当指标是一个对象的办法或者是一个依赖 this 独立运行的函数时,因为函数被.throw 调用时会失落原有的 this 环境而无奈得悉所谓的 this 到底指什么。对于这个问题目前有两种计划,第一种是将办法或函数在另一个函数中调用,另一种形式是应用 bind 进行绑定
.throws 和.Throw 能够与.throw 调换

.respondTo(method[, msg])
当指标是一个非函数对象时,.respondTo 断言该对象蕴含所提供办法名称的办法,该办法能够是本身的也能够是继承的,能够是可枚举也能够时不可枚举的。
当指标是一个函数时断言该函数原型属性又一个与所给名称雷同的办法。同样的,该办法能够是本身的也能够是继承的,能够是可枚举也能够时不可枚举的。

.itself
强制链中的所有断言体现得如同指标是非函数对象,即便它是一个函数。因而,它导致断言指标具备给定名称的办法,而不是断言指标的原型属性具备给定名称的办法。

.satisfy(matcher[, msg])
将目标值作为所给 matcher 办法的第一个参数进行调用,并断言返回值为真。

.closeTo(expected, delta[, msg])
断言目标值是一个基于期待值(expected)+/- 差值(delta)范畴内的数字。

.members(set[, msg])
断言指标数组与所给数组 set 具备雷同成员。
默认状况下是断言成员严格相等,在链式之前减少.deep 能够使应用深度相等的形式代替严格相等

// 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}]);

默认状况下,程序是不进行匹配的。在链式之前增加.ordered 能够使得成员匹配依照雷同的程序进行。
expect([1, 2, 3]).to.have.ordered.members([1, 2, 3]);
expect([1, 2, 3]).to.have.members([2, 1, 3]) .but.not.ordered.members([2, 1, 3]);
默认状况下,指标数组应与所给数组集放弃雷同 size,在链式之前增加.include 能够使得指标数组为期待数组的一个超集。须要留神的是在增加.include 后,子集中反复的成员是会被疏忽的
.deep、.include 和.ordered 都能够与其联结应用。值得注意的是,当链式中存在.include 和.ordered 时,期待数组与指标数组应该放弃雷同的程序。
expect([{a: 1}, {b: 2}, {c: 3}]) .to.include.deep.ordered.members([{a: 1}, {b: 2}])
.but.not.include.deep.ordered.members([{b: 2}, {c: 3}]);

.oneOf(list[, msg])
断言指标期间待数组 list 的成员,但最好的形式时断言其为某个确认的值。
将会以严格相等的形式进行比拟。

.change(subject[, prop[, msg]])
当一个参数被给定时。.change 断言给定函数 subject 在指标函数之前调用和在指标函数之后调用的返回值不同。但更好的形式时断言函数会返回具体的某个值。
当有两个函数被提供时,.change 断言对象 subject 的属性 prop 在指标函数调用前后的值是不同的。

.increase(subject[, prop[, msg]])
当一个参数被给定时。.increase 断言给定函数 subject 在指标函数之后调用比在指标函数之前调用的返回值更大。但更好的形式是断言函数会减少具体的数值而不是断言他会减少任意数值。

var myObj = {val: 1}
  , subtractTwo = function () { myObj.val -= 2;};
expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
expect(subtractTwo).to.not.increase(myObj, 'val'); // Not recommended

当有两个函数被提供时,.increase 断言对象 subject 的属性 prop 在指标函数调用后比调用之前更大。

.decrease(subject[, prop[, msg]])
当一个参数被给定时。.decrease 断言给定函数 subject 在指标函数之后调用比在指标函数之前调用的返回值更小。但更好的形式是断言函数会缩小具体的数值而不是断言他会缩小任意数值。

var val = 1
  , subtractTwo = function () { val -= 2;}
  , getVal = function () { return val;};

expect(subtractTwo).to.decrease(getVal).by(2); // Recommended
expect(subtractTwo).to.decrease(getVal); // Not recommended

当有两个函数被提供时,.increase 断言对象 subject 的属性 prop 在指标函数调用后比调用之前更小。

.by(delta[, msg])
当.by 跟在.increase 链式断言之后,.by 断言.increase 断言的增量为给定的差值(delta)。
当.by 跟在.decrease 链式断言之后,.by 断言.decrease 断言的缩小量为给定的差值(delta)。
当.by 跟在.change 链式断言之后,.by 断言.change 断言的差量为给定的差值(delta)。但这样做会产生问题,因为这将会产生一个不确定的期待,通常最好的做法是确认一个精准的期待输入,而只用准确输入去断言。

var myObj = {val: 1}
  , addTwo = function () { myObj.val += 2;}
  , subtractTwo = function () { myObj.val -= 2;};

expect(addTwo).to.increase(myObj, 'val').by(2); // 举荐的做法
expect(addTwo).to.change(myObj, 'val').by(2); // 不举荐的做法

expect(subtractTwo).to.decrease(myObj, 'val').by(2); // 举荐的做法
expect(subtractTwo).to.change(myObj, 'val').by(2); // 不举荐的做法

.extensible
断言指标是可扩大的,这意味着能够向其增加新属性。原始值是相对不可扩大的。在.extensible 链式构造之前增加.not 能够否定.extensible.

译注:对象的可拓展性用以示意是否能够给对象增加新属性。所有内置对象和自定义对象都是显示可拓展的,除非将它们转换为不可拓展的。同样,宿主对象的可拓展性也是由实现 ECMAScript5 的 IavaScript 引擎定义的。

var nonExtensibleObject = Object.preventExtensions({})
  , sealedObject = Object.seal({})
  , frozenObject = Object.freeze({});

expect(nonExtensibleObject).to.not.be.extensible;
expect(sealedObject).to.not.be.extensible;
expect(frozenObject).to.not.be.extensible;
expect(1).to.not.be.extensible;

其错误信息仅能够作为 expect 的第二个参数被给出。

expect(1, 'nooo why fail??').to.be.extensible;

.sealed
断言指标是密封的,这意味着将无奈退出新属性,并且已存在的属性无奈重新配置或者删除,这也意味着已存在的属性在重新分配不同值之后依然可能放弃。原始值均是密封的。

var sealedObject = Object.seal({});
var frozenObject = Object.freeze({});

expect(sealedObject).to.be.sealed;
expect(frozenObject).to.be.sealed;
expect(1).to.be.sealed;

在.sealed 链式构造之前增加.not 能够否定.sealed。

expect({a: 1}).to.not.be.sealed;

其错误信息仅能够作为 expect 的第二个参数被给出。

expect({a: 1}, 'nooo why fail??').to.be.sealed;

.frozen
断言指标是密封的,这意味着将无奈退出新属性,并且已存在的属性无奈被重新分配值,重新配置或者删除。原始值总是解冻的。

var frozenObject = Object.freeze({});

expect(frozenObject).to.be.frozen;
expect(1).to.be.frozen;

在.frozen 链式构造之前增加.not 能够否定.frozen。

expect({a: 1}).to.not.be.frozen;

其错误信息仅能够作为 expect 的第二个参数被给出。

expect({a: 1}, 'nooo why fail??').to.be.frozen;

.finite
断言指标是一个非 NaN 的数字,且该数字既不是正无穷也是负无穷。

expect(1).to.be.finite;

能够在链式之前减少.not 进行否定,但这样的做法是危险的,因为这将会产生一个不确定的期待,它可能不是一个数字,或者是 NaN,也可能是正无穷或者负无穷。所以通常最好的做法是期待它产生一个准确的输入,而后仅仅去断言可能会产生的期待。
当指标不被期待是一个数字是最好是去断言它是某个你期待的类型,而不是断言它是许多个不合乎断言的类型之一。

expect('foo').to.be.a('string'); // Recommended
expect('foo').to.not.be.finite; // Not recommended

其错误信息仅能够作为 expect 的第二个参数被给出。

expect('foo', 'nooo why fail??').to.be.finite;

**.fail([message])
.fail(actual, expected, [message], [operator])**
抛出一个谬误。

expect.fail();
expect.fail("custom error message");
expect.fail(1, 2);
expect.fail(1, 2, "custom error message");
expect.fail(1, 2, "custom error message", ">");
expect.fail(1, 2, undefined, ">");

译注:当仅有一个参数传入时抛出一个谬误,将所传入信息作为错误信息。当传入三个参数时,别离 传入理论值,期待的值和谬误提醒,并将这个谬误抛出。

退出移动版