詳解Chai.js斷言庫(kù)API中文文檔
Chai.js斷言庫(kù)API中文文檔
基于chai.js官方API文檔翻譯。僅列出BDD風(fēng)格的expect/should API。TDD風(fēng)格的Assert API由于不打算使用,暫時(shí)不放,后續(xù)可能會(huì)更新。
BDD
expect和should是BDD風(fēng)格的,二者使用相同的鏈?zhǔn)秸Z言來組織斷言,但不同在于他們初始化斷言的方式:expect使用構(gòu)造函數(shù)來創(chuàng)建斷言對(duì)象實(shí)例,而should通過為Object.prototype新增方法來實(shí)現(xiàn)斷言(所以should不支持IE);expect直接指向chai.expect,而should則是chai.should()。
個(gè)人比較建議使用expect,should不僅不兼容IE,在某些情況下還需要改變斷言方式來填坑。詳細(xì)的比較可以看看官網(wǎng)Assertion Styles,說的很清楚。
var chai = require('chai') , expect = chai.expect , should = chai.should()
語言鏈
下面的接口是單純作為語言鏈提供以期提高斷言的可讀性。除非被插件改寫否則它們一般不提供測(cè)試功能。
- to
- be
- been
- is
- that
- which
- and
- has
- have
- with
- at
- of
- same
.not
對(duì)之后的斷言取反
expect(foo).to.not.equal('bar') expect(goodFn).to.not.throw(Error) expect({ foo: 'baz'}).to.have.property('foo') .and.not.equal('bar')
.deep
設(shè)置deep標(biāo)記,然后使用equal和property斷言。該標(biāo)記可以讓其后的斷言不是比較對(duì)象本身,而是遞歸比較對(duì)象的鍵值對(duì)
expect(foo).to.deep.equal({ bar: 'baz'}) expect({ foo: { bar: { baz: 'quux'}}}) .to.have.deep.property('foo.bar.baz', 'quux')
deep.property中的特殊符號(hào)可以使用雙反斜杠進(jìn)行轉(zhuǎn)義(第一個(gè)反斜杠是在字符串參數(shù)中對(duì)第二個(gè)反斜杠進(jìn)行轉(zhuǎn)義,第二個(gè)反斜杠用于在property中進(jìn)行轉(zhuǎn)義)
var deepCss = { '.link': { '[target]': 42 } } expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42)
.any
在keys斷言之前使用any標(biāo)記(與all相反)
expect(foo).to.have.any.keys('bar', 'baz')
.all
在keys斷言之前使用all標(biāo)記(與any相反)
expect(foo).to.have.all.keys('bar', 'baz')
.a(type) / .an(type)
type:String,被測(cè)試的值的類型
a和an斷言即可作為語言鏈又可作為斷言使用
// 類型斷言 expect('test').to.be.a('string'); expect({ foo: 'bar' }).to.be.an('object'); expect(null).to.be.a('null'); expect(undefined).to.be.an('undefined'); expect(new Error).to.be.an('error'); expect(new Promise).to.be.a('promise'); expect(new Float32Array()).to.be.a('float32array'); expect(Symbol()).to.be.a('symbol'); // es6 overrides expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo'); // language chain expect(foo).to.be.an.instanceof(Foo);
.include(value) / contains(value)
value:Object | String | Number
include()和contains()即可作為屬性類斷言前綴語言鏈又可作為作為判斷數(shù)組、字符串是否包含某值的斷言使用。當(dāng)作為語言鏈?zhǔn)褂脮r(shí),常用于key()斷言之前
expect([1, 2, 3]).to.include(2) expect('foobar').to.include('bar') expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo')
.ok
斷言目標(biāo)為真值。
expect('everything').to.be.ok expect(1).to.be.ok expect(false).to.not.be.ok expect(null).to.not.be.ok
.true
斷言目標(biāo)為true,注意,這里與ok的區(qū)別是不進(jìn)行類型轉(zhuǎn)換,只能為true才能通過斷言
expect(true).to.be.true expect(1)to.not.be.true
.false
斷言目標(biāo)為false
expect(false).to.be.false expect(0).to.not.be.false
.null
斷言目標(biāo)為null
expect(null).to.be.null expect(undefined).to.not.be.null
.undefined
斷言目標(biāo)為undefined。
expect(undefine).to.be.undefined expect(null).to.not.be.undefined
.NaN
斷言目標(biāo)為非數(shù)字NaN
expect('foo').to.be.null expect(4)to.not.be.null
.exist
斷言目標(biāo)存在,即非null也非undefined
var foo = 'hi', bar = null, baz expect(foo).to.exist expect(bar).to.not.exist expect(baz).to.not.exist
.empty
斷言目標(biāo)的長(zhǎng)度為0。對(duì)于數(shù)組和字符串,它檢查length屬性,對(duì)于對(duì)象,它檢查可枚舉屬性的數(shù)量
expect([]).to.be.empty expect('').to.be.empty expect({}).to.be.empty
.arguments
斷言目標(biāo)是一個(gè)參數(shù)對(duì)象arguments
function test () { expect(arguments).to.be.arguments }
.equal(value)
value:Mixed
斷言目標(biāo)嚴(yán)格等于(===)value。另外,如果設(shè)置了deep標(biāo)記,則斷言目標(biāo)深度等于value
expect('hello').to.equal('hello') expect(42).to.equal(42) expect(1).to.not.equal(true) expect({ foo: 'bar'}).to.not.equal({ foo: 'bar'}) expect({ foo: 'bar'}).to.deep.equal({foo: 'bar'})
.eql(value)
value:Mixed
斷言目標(biāo)深度等于value,相當(dāng)于deep.equal(value)的簡(jiǎn)寫
expect({ foo: 'bar' }).to.eql({ foo: 'bar' }) expect([1, 2, 3]).to.eql([1, 2, 3])
.above(value)
value: Number
斷言目標(biāo)大于(超過)value
expect(10).to.be.above(5)
也可接在length后來斷言一個(gè)最小的長(zhǎng)度。相比直接提供長(zhǎng)度的好處是提供了更詳細(xì)的錯(cuò)誤消息
expect('foo').to.have.length.above(2) expect([1, 2, 3]).to.have.length.above(2)
.least(value)
value: Number
斷言目標(biāo)不小于(大于或等于)value
expect(10).to.be.at.least(10)
也可接在length后來斷言一個(gè)最小的長(zhǎng)度。相比直接提供長(zhǎng)度的好處是提供了更詳細(xì)的錯(cuò)誤消息
expect('foo').to.have.length.of.at.least(3) expect([1, 2, 3]).to.have.length.of.at.least(3)
.below(value)
value:Number
斷言目標(biāo)小于value
expect(5).to.be.below(10)
也可接在length后來斷言一個(gè)最大的長(zhǎng)度。相比直接提供長(zhǎng)度的好處是提供了更詳細(xì)的錯(cuò)誤消息
expect('foo').to.have.length.below(4) expect([1, 2, 3]).to.have.length.below(4)
.most(value)
value:String
斷言目標(biāo)不大于(小于或等于)value
expect(5).to.be.at.most(5)
也可接在length后來斷言一個(gè)最大的長(zhǎng)度。相比直接提供長(zhǎng)度的好處是提供了更詳細(xì)的錯(cuò)誤消息
expect('foo').to.have.length.of.at.most(4) expect([1, 2, 3]).to.have.length.of.at.most(3)
.within(start, finish)
start:Number,下限
finish:Number,上限
斷言目標(biāo)在某個(gè)區(qū)間內(nèi)
expect(7).to.be.within(5, 10)
也可接在length后來斷言一個(gè)長(zhǎng)度區(qū)間。相比直接提供長(zhǎng)度的好處是提供了更詳細(xì)的錯(cuò)誤消息
expect('foo').to.have.length.within(2, 4) expect([1, 2, 3]).to.have.length.within(2, 4)
.instanceof(constructor)
constructor:Constructor,構(gòu)造函數(shù)
斷言目標(biāo)是構(gòu)造函數(shù)constructor的一個(gè)實(shí)例
var Tea = function (name) { this.name = name }, Chai = new Tea('chai') expect(Chai).to.be.an.instanceof(Tea) expect([1, 2, 3]).to.be.an.instanceof(Array)
.property(name, [value])
name:String,屬性名
value:Mixed,可選,屬性值
斷言目標(biāo)是否擁有某個(gè)名為name的屬性,可選地如果提供了value則該屬性值還需要嚴(yán)格等于(===)value。如果設(shè)置了deep標(biāo)記,則可以使用點(diǎn).和中括號(hào)[]來指向?qū)ο蠛蛿?shù)組中的深層屬性
// 簡(jiǎn)單引用 var obj = { foo: 'bar' } expect(obj).to.have.property('foo') expect(pbj).to.have.property('foo', 'bar') // 深層引用 var deepObj = { green: { tea: 'matcha' }, teas: [ 'Chai', 'matcha', { tea: 'konacha' } ] } expect(deepObj).to.have.deep.property('green.tea', 'matcha') expect(deepObj).to.have.deep.property('teas[1]', 'matcha') expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha')
如果目標(biāo)是一個(gè)數(shù)組,還可以直接使用一個(gè)或多個(gè)數(shù)組下標(biāo)作為name來在嵌套數(shù)組中斷言deep.property
var arr = [ [ 'chai', 'matcha', 'konacha' ], [ { tea: 'chai' }, { tea: 'matcha' }, { tea: 'konacha' } ] ] expect(arr).to.have.deep.property('[0][1]', 'matcha') expect(arr).to.have.deep.property('[1][2].tea', 'konacha')
此外,property把斷言的主語(subject)從原來的對(duì)象變?yōu)楫?dāng)前屬性的值,使得可以在其后進(jìn)一步銜接其它鏈?zhǔn)綌嘌裕▉磲槍?duì)這個(gè)屬性值進(jìn)行測(cè)試)
expect(obj).to.have.property('foo') .that.is.a('string') expect(deepObj).to.have.property('green') .that.is.an('object') .that.deep.equals({ tea: 'matcha' }) expect(deepObj).to.have.property('teas') .that.is.an('array') .with.deep.property('[2]') .that.deep.equals({ tea: 'konacha' })
注意,只有當(dāng)設(shè)置了deep標(biāo)記的時(shí)候,在property() name中的點(diǎn)(.)和中括號(hào)([])才必須使用雙反斜杠\進(jìn)行轉(zhuǎn)義(為什么是雙反斜杠,在前文有提及),當(dāng)沒有設(shè)置deep標(biāo)記的時(shí)候,是不能進(jìn)行轉(zhuǎn)義的
// 簡(jiǎn)單指向 var css = { '.link[target]': 42 } expect(css).to.have.property('.link[target]', 42) //深度指向 var deepCss = { 'link': { '[target]': 42 } } expect(deepCss).to.have.deep.property('\\.link\\.[target]', 42)
.ownProperty(name)
name:String,屬性名
斷言目標(biāo)擁有名為name的自有屬性
expect('test').to.have.ownProperty('length')
.ownPropertyDescription(name[, descriptor])
- name:String,屬性名
- descriptor: Object,描述對(duì)象,可選
斷言目標(biāo)的某個(gè)自有屬性存在描述符對(duì)象,如果給定了descroptor描述符對(duì)象,則該屬性的描述符對(duì)象必須與其相匹配
expect('test').to.have.ownPropertyDescriptor('length') expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configrable: false, writeable: false, value: 4 }) expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writeable: false, value: 3 }) // 將斷言的主語改為了屬性描述符對(duì)象 expect('test').to.have.ownPropertyDescriptor('length') .to.have.property('enumerable', false) expect('test').to.have.ownPropertyDescriptor('length') .to.have.keys('value')
.length
設(shè)置.have.length標(biāo)記作為比較length屬性值的前綴
expect('foo').to.have.length.above(2) expect([1, 2, 3]).to.have.length.within(2, 4)
.lengthOf(value)
value:Number
斷言目標(biāo)的length屬性為期望的值
expect([1, 2, 3]).to.have.lengthOf(3) expect('foobar').to.have.lengthOf(6)
.match(regexp)
regexp:RegExp,正則表達(dá)式
斷言目標(biāo)匹配到一個(gè)正則表達(dá)式
expect('foobar').to.match(/^foo/)
.string(string)
string:String,字符串
斷言目標(biāo)字符串包含另一個(gè)字符串
expect('foobar').to.have.string('bar')
.keys(key1, [key2], [...])
key:String | Array | Object 屬性名
斷言目標(biāo)包含傳入的屬性名。與any,all,contains或者h(yuǎn)ave前綴結(jié)合使用會(huì)影響測(cè)試結(jié)果:
當(dāng)與any結(jié)合使用時(shí),無論是使用have還是使用contains前綴,目標(biāo)必須至少存在一個(gè)傳入的屬性名才能通過測(cè)試。注意,any或者all應(yīng)當(dāng)至少使用一個(gè),否則默認(rèn)為all
當(dāng)結(jié)合all和contains使用時(shí),目標(biāo)對(duì)象必須至少擁有全部傳入的屬性名,但是它也可以擁有其它屬性名
當(dāng)結(jié)合all和have使用時(shí),目標(biāo)對(duì)象必須且僅能擁有全部傳入的屬性名
// 結(jié)合any使用 expect({ foo: 1, bar: 2, baz: 3 }).to.have.any.keys('foo', 'bar') expect({ foo: 1, bar: 2, baz: 3 }).to.contains.any.keys('foo', 'bar') // 結(jié)合all使用 expect({ foo: 1, bar: 2, baz: 3 }).to.have.all.keys('foo', 'bar', 'baz') expect({ foo: 1, bar: 2, baz: 3 }).to.contains.all.keys('foo', 'bar') // 傳入string expect({ foo: 1, bar: 2, baz: 3 }).to.have.any.keys('foo') // 傳入Array expect({ foo: 1, bar: 2, baz: 3 }).to.have.all.keys(['foo', 'bar', 'baz']) // 傳入Object expect({ foo: 1, bar: 2, baz: 3 }).to.have.any.keys({ bar: 2, foo: 1 })
.throw(constructor)
constructor: ErrorConstroctor | String | RegExp
斷言目標(biāo)函數(shù)會(huì)拋出一個(gè)指定錯(cuò)誤或錯(cuò)誤類型(使用instanceOf計(jì)算),也可使用正則表達(dá)式或者字符串來檢測(cè)錯(cuò)誤消息
var err = new RefernceError('this is a bad function') var fn = function () { throw err } expect(fn).to.throw(ReferenceError) expect(fn).to.throw(Error) expect(fn).to.throw(/bad function/) expect(fn).to.not.throw('good function') expect(fn).to.throw(ReferrenceError, /bad function/) expect(fn).to.throw(err)
注意,當(dāng)一個(gè)拋錯(cuò)斷言被否定了(前面有.not),那么它會(huì)從Error構(gòu)造函數(shù)開始依次檢查各個(gè)可能傳入的參數(shù)。檢查一個(gè)只是消息類型不匹配但是已知的錯(cuò)誤,合理的方式是先斷言該錯(cuò)誤存在,然后使用.and后斷言錯(cuò)誤消息不匹配
expect(fn).to.throw(ReferenceError) .and.not.throw(/good function/)
.respondTo(method)
method:String
斷言目標(biāo)類或?qū)ο髸?huì)響應(yīng)一個(gè)方法(存在這個(gè)方法)
Klass.prototype.bar = function () {} expect(Klass).to.respondTo('bar') expect(obj).to.respondTo('bar')
如果需要檢查一個(gè)構(gòu)造函數(shù)是否會(huì)響應(yīng)一個(gè)靜態(tài)方法(掛載在構(gòu)造函數(shù)本身的方法),請(qǐng)查看itself標(biāo)記
Klass.baz = function () {} expect(Klass).itself.to.respondTo('baz')
.itself
設(shè)置itself標(biāo)記,然后使用respondTo斷言
function Foo () {} Foo.bar = function () {} Foo.prototype.baz = function () {} expect(Foo).itself.to.respondTo('bar') expect(Foo).itself.not.to.respond('baz')
.satisfy(method)
method:Function,測(cè)試器,接受一個(gè)參數(shù)表示目標(biāo)值,返回一個(gè)布爾值
斷言目標(biāo)值能夠讓給定的測(cè)試器返回真值
expect(1).to.satisfy(function (num) { return num > 0 })
.closeTo(expected, delta)
expect:Numbre,期望值
delta:Numbre,范圍半徑
斷言目標(biāo)數(shù)字等于expected,或在期望值的+/-delta范圍內(nèi)
expect(1.5).to.be.closeTo(1, 0.5)
.members(set)
set:Array
斷言目標(biāo)是set的超集,或前者有后者所有嚴(yán)格相等(===)的成員。另外,如果設(shè)置了deep標(biāo)記,則成員進(jìn)行深度比較(include/contains只能接受單個(gè)值,但它們的主語除了是數(shù)組,還可以判斷字符串;members則將它們的能力擴(kuò)展為能夠接受一個(gè)數(shù)組,但主語只能是數(shù)組)
expect([1, 2, 3]).to.include.members([3, 2]) expect([1, 2, 3]).to.not.include.members([3, 2, 8]) expect([4, 2]).to.have.members([2, 4]) expect([5, 2]).to.not.have.members([5, 2, 1]) expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }])
.oneOf(list)
list:Array
斷言目標(biāo)值出現(xiàn)在list數(shù)組的某個(gè)頂層位置(直接子元素,嚴(yán)格相等)
expect('a').to.be.oneOf(['a', 'b', 'c']) expect(9).to.not.be.oneOf(['z']) // 嚴(yán)格相等,所以對(duì)象類的值必須為同一個(gè)引用才能被判定為相等 var three = [3] expect([3]).to.not.be.oneOf([1, 2, [3]]) expect(three).to.not.be.oneOf([1, 2, [3]]) expect(three).to.be.oneOf([1, 2, three])
change(object, property)
- object:Object,對(duì)象
- property:String,屬性名
斷言目標(biāo)方法會(huì)改變指定對(duì)象的指定屬性
var obj = { val: 10 } var fn = function () { obj.val += 3 } var noChangeFn = function () { return 'bar' + 'baz' } expect(fn).to.change(obj, 'val')
.increase(object, property)
- object:Object,對(duì)象
- property:String,屬性名
斷言目標(biāo)方法會(huì)增加指定對(duì)象的屬性
var obj = { val: 10 } var fn = function () { obj.val = 15 } expect(fn).to.increase(obj, val)
.decrease(object, property)
- object:Object,對(duì)象
- property:String,屬性名
斷言目標(biāo)方法會(huì)減少指定對(duì)象的屬性
var obj = { val: 10 } var fn = function () { obj.val = 5 } expect(fn).to.decrease(obj, val)
.extensible
斷言目標(biāo)對(duì)象是可擴(kuò)展的(可以添加新的屬性)
var nonExtensibleObject = Object.preventExtensions({}) var sealedObject = Object.seal({}) var frozenObject = Object.freeze({}) expect({}).to.be.extensible expect(nonExtensibleObject).to.not.be.extensible expect(sealObject).to.not.be.extensible expect(frozenObject).to.not.be.extensible
.sealed
斷言目標(biāo)對(duì)象是封閉的(無法添加新的屬性并且存在的屬性不能被刪除但可以被修改)
var sealedObject= Object.seal({}) var frozenObject = Object.freeze({}) expect(sealedObject).to.be.sealed expect(frozenObject).to.be.sealed expect({}).to.not.be.sealed
.frozen
斷言目標(biāo)對(duì)象是凍結(jié)的(無法添加新的屬性并且存在的屬性不能被刪除和修改)
var frozenObject = Object.freeze({}) expect(frozenObject).to.be.frozen expect({}).to.not.be.frozen
TDD
除了一些語法糖以外,Chai提供的assert風(fēng)格的斷言和node.js包含的assert模塊非常相似。assert風(fēng)格是三種斷言風(fēng)格中唯一不支持鏈?zhǔn)秸{(diào)用的。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
獲取URL地址中的文件名和參數(shù)的javascript代碼
JS 獲取URL地址中的文件名和參數(shù),這個(gè)版本中有詳細(xì)的注釋。2009-09-09詳解JavaScript私有類字段和TypeScript私有修飾符
這篇文章主要介紹了JavaScript私有類字段和TypeScript私有修飾符,對(duì)私有類感興趣的同學(xué),可以參考下2021-04-04JavaScript中立即執(zhí)行函數(shù)實(shí)例詳解
javascript和其他編程語言相比比較隨意,所以javascript代碼中充滿各種奇葩的寫法,有時(shí)霧里看花,當(dāng)然,能理解各型各色的寫法也是對(duì)javascript語言特性更進(jìn)一步的深入理解。這篇文章主要給大家介紹了關(guān)于JavaScript中立即執(zhí)行函數(shù)的相關(guān)資料,需要的朋友可以參考下。2017-11-11js創(chuàng)建數(shù)據(jù)共享接口——簡(jiǎn)化框架之間相互傳值
很多框架存在父子關(guān)系,操作起來十分麻煩,很多同學(xué)經(jīng)常出現(xiàn)這樣悲催的代碼2011-10-10js實(shí)現(xiàn)兩點(diǎn)之間畫線的方法
這篇文章主要介紹了js實(shí)現(xiàn)兩點(diǎn)之間畫線的方法,涉及javascript圖形繪制的相關(guān)技巧,需要的朋友可以參考下2015-05-05提高團(tuán)隊(duì)代碼質(zhì)量利器ESLint及Prettier詳解
這篇文章主要為大家介紹了提高團(tuán)隊(duì)代碼質(zhì)量利器ESLint及Prettier使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11小程序getLocation需要在app.json中聲明permission字段
這篇文章主要介紹了小程序getLocation需要在app.json中聲明permission字段,個(gè)別需要獲取用戶地理位置的在開發(fā)者工具調(diào)試時(shí)會(huì)出現(xiàn)getLocation需要在app.json中聲明permission字段 ,下面我們就一起來解決一下2019-04-04