詳解Chai.js斷言庫API中文文檔,詳解chai.js斷言api

來源:互聯網
上載者:User

詳解Chai.js斷言庫API中文文檔,詳解chai.js斷言api

Chai.js斷言庫API中文文檔

基於chai.js官方API文檔翻譯。僅列出BDD風格的expect/should API。TDD風格的Assert API由於不打算使用,暫時不放,後續可能會更新。

BDD

expect和should是BDD風格的,二者使用相同的鏈式語言來組織斷言,但不同在於他們初始化斷言的方式:expect使用建構函式來建立斷言對象執行個體,而should通過為Object.prototype新增方法來實現斷言(所以should不支援IE);expect直接指向chai.expect,而should則是chai.should()。

個人比較建議使用expect,should不僅不相容IE,在某些情況下還需要改變斷言方式來填坑。詳細的比較可以看看官網Assertion Styles,說的很清楚。

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

語言鏈

下面的介面是單純作為語言鏈提供以期提高斷言的可讀性。除非被外掛程式改寫否則它們一般不提供測試功能。

  1. to
  2. be
  3. been
  4. is
  5. that
  6. which
  7. and
  8. has
  9. have
  10. with
  11. at
  12. of
  13. same

.not

對之後的斷言取反

expect(foo).to.not.equal('bar')expect(goodFn).to.not.throw(Error)expect({ foo: 'baz'}).to.have.property('foo') .and.not.equal('bar')

.deep

設定deep標記,然後使用equal和property斷言。該標記可以讓其後的斷言不是比較對象本身,而是遞迴比較對象的索引值對

expect(foo).to.deep.equal({ bar: 'baz'})expect({ foo: { bar: { baz: 'quux'}}}) .to.have.deep.property('foo.bar.baz', 'quux')

deep.property中的特殊符號可以使用雙反斜線進行轉義(第一個反斜線是在字串參數中對第二個反斜線進行轉義,第二個反斜線用於在property中進行轉義)

var deepCss = { '.link': { '[target]': 42 } }expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42)

.any

在keys斷言之前使用any標記(與all相反)

expect(foo).to.have.any.keys('bar', 'baz')

.all

在keys斷言之前使用all標記(與any相反)

expect(foo).to.have.all.keys('bar', 'baz')

.a(type) / .an(type)

type:String,被測試的值的類型

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 overridesexpect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');// language chainexpect(foo).to.be.an.instanceof(Foo);

.include(value) / contains(value)

value:Object | String | Number

include()和contains()即可作為屬性類斷言首碼語言鏈又可作為作為判斷數組、字串是否包含某值的斷言使用。當作為語言鏈使用時,常用於key()斷言之前

expect([1, 2, 3]).to.include(2)expect('foobar').to.include('bar')expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo')

.ok

斷言目標為真值。

expect('everything').to.be.okexpect(1).to.be.okexpect(false).to.not.be.okexpect(null).to.not.be.ok

.true

斷言目標為true,注意,這裡與ok的區別是不進行類型轉換,只能為true才能通過斷言

expect(true).to.be.trueexpect(1)to.not.be.true

.false

斷言目標為false

expect(false).to.be.falseexpect(0).to.not.be.false

.null

斷言目標為null

expect(null).to.be.nullexpect(undefined).to.not.be.null

.undefined

斷言目標為undefined。

expect(undefine).to.be.undefinedexpect(null).to.not.be.undefined

.NaN

斷言目標為非數字NaN

expect('foo').to.be.nullexpect(4)to.not.be.null

.exist

斷言目標存在,即非null也非undefined

var foo = 'hi', bar = null, bazexpect(foo).to.existexpect(bar).to.not.existexpect(baz).to.not.exist

.empty

斷言目標的長度為0。對於數組和字串,它檢查length屬性,對於對象,它檢查可枚舉屬性的數量

expect([]).to.be.emptyexpect('').to.be.emptyexpect({}).to.be.empty

.arguments

斷言目標是一個參數對象arguments

function test () { expect(arguments).to.be.arguments}

.equal(value)

value:Mixed

斷言目標嚴格等於(===)value。另外,如果設定了deep標記,則斷言目標深度等於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

斷言目標深度等於value,相當於deep.equal(value)的簡寫

expect({ foo: 'bar' }).to.eql({ foo: 'bar' })expect([1, 2, 3]).to.eql([1, 2, 3])

.above(value)

value: Number

斷言目標大於(超過)value

expect(10).to.be.above(5)

也可接在length後來斷言一個最小的長度。相比直接提供長度的好處是提供了更詳細的錯誤訊息

expect('foo').to.have.length.above(2)expect([1, 2, 3]).to.have.length.above(2)

.least(value)

value: Number

斷言目標不小於(大於或等於)value

expect(10).to.be.at.least(10)

也可接在length後來斷言一個最小的長度。相比直接提供長度的好處是提供了更詳細的錯誤訊息

expect('foo').to.have.length.of.at.least(3)expect([1, 2, 3]).to.have.length.of.at.least(3)

.below(value)

value:Number

斷言目標小於value

expect(5).to.be.below(10)

也可接在length後來斷言一個最大的長度。相比直接提供長度的好處是提供了更詳細的錯誤訊息

expect('foo').to.have.length.below(4)expect([1, 2, 3]).to.have.length.below(4)

.most(value)

value:String

斷言目標不大於(小於或等於)value

expect(5).to.be.at.most(5)

也可接在length後來斷言一個最大的長度。相比直接提供長度的好處是提供了更詳細的錯誤訊息

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,上限

斷言目標在某個區間內

expect(7).to.be.within(5, 10)

也可接在length後來斷言一個長度區間。相比直接提供長度的好處是提供了更詳細的錯誤訊息

expect('foo').to.have.length.within(2, 4)expect([1, 2, 3]).to.have.length.within(2, 4)

.instanceof(constructor)

constructor:Constructor,建構函式

斷言目標是建構函式constructor的一個執行個體

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,可選,屬性值

斷言目標是否擁有某個名為name的屬性,可選地如果提供了value則該屬性值還需要嚴格等於(===)value。如果設定了deep標記,則可以使用點.和中括弧[]來指向對象和數組中的深層屬性

// 簡單引用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')

如果目標是一個數組,還可以直接使用一個或多個數組下標作為name來在嵌套數組中斷言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)從原來的對象變為當前屬性的值,使得可以在其後進一步銜接其它鏈式斷言(來針對這個屬性值進行測試)

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' })

注意,只有當設定了deep標記的時候,在property() name中的點(.)和中括弧([])才必須使用雙反斜線\進行轉義(為什麼是雙反斜線,在前文有提及),當沒有設定deep標記的時候,是不能進行轉義的

// 簡單指向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,屬性名稱

斷言目標擁有名為name的自有屬性

expect('test').to.have.ownProperty('length')

.ownPropertyDescription(name[, descriptor])

  1. name:String,屬性名稱
  2. descriptor: Object,描述對象,可選

斷言目標的某個自有屬性存在描述符對象,如果給定了descroptor描述符對象,則該屬性的描述符對象必須與其相匹配

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 })// 將斷言的主語改為了屬性描述符對象expect('test').to.have.ownPropertyDescriptor('length') .to.have.property('enumerable', false)expect('test').to.have.ownPropertyDescriptor('length') .to.have.keys('value')

.length

設定.have.length標記作為比較length屬性值的首碼

expect('foo').to.have.length.above(2)expect([1, 2, 3]).to.have.length.within(2, 4)

.lengthOf(value)

value:Number

斷言目標的length屬性為期望的值

expect([1, 2, 3]).to.have.lengthOf(3)expect('foobar').to.have.lengthOf(6)

.match(regexp)

regexp:RegExp,Regex

斷言目標匹配到一個Regex

expect('foobar').to.match(/^foo/)

.string(string)

string:String,字串

斷言目標字串包含另一個字串

expect('foobar').to.have.string('bar')

.keys(key1, [key2], [...])

key:String | Array | Object 屬性名稱

斷言目標包含傳入的屬性名稱。與any,all,contains或者have首碼結合使用會影響測試結果:

當與any結合使用時,無論是使用have還是使用contains首碼,目標必須至少存在一個傳入的屬性名稱才能通過測試。注意,any或者all應當至少使用一個,否則預設為all

當結合all和contains使用時,目標對象必須至少擁有全部傳入的屬性名稱,但是它也可以擁有其它屬性名稱

當結合all和have使用時,目標對象必須且僅能擁有全部傳入的屬性名稱

// 結合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')// 結合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')// 傳入stringexpect({ foo: 1, bar: 2, baz: 3 }).to.have.any.keys('foo')// 傳入Arrayexpect({ foo: 1, bar: 2, baz: 3 }).to.have.all.keys(['foo', 'bar', 'baz'])// 傳入Objectexpect({ foo: 1, bar: 2, baz: 3 }).to.have.any.keys({ bar: 2, foo: 1 })

.throw(constructor)

constructor: ErrorConstroctor | String | RegExp

斷言目標函數會拋出一個指定錯誤或錯誤類型(使用instanceOf計算),也可使用Regex或者字串來檢測錯誤訊息

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)

注意,當一個拋錯斷言被否定了(前面有.not),那麼它會從Error建構函式開始依次檢查各個可能傳入的參數。檢查一個只是訊息類型不匹配但是已知的錯誤,合理的方式是先斷言該錯誤存在,然後使用.and後斷言錯誤訊息不匹配

expect(fn).to.throw(ReferenceError) .and.not.throw(/good function/)

.respondTo(method)

method:String

斷言目標類或對象會響應一個方法(存在這個方法)

Klass.prototype.bar = function () {}expect(Klass).to.respondTo('bar')expect(obj).to.respondTo('bar')

如果需要檢查一個建構函式是否會響應一個靜態方法(掛載在建構函式本身的方法),請查看itself標記

Klass.baz = function () {}expect(Klass).itself.to.respondTo('baz')

.itself

設定itself標記,然後使用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,測試器,接受一個參數表示目標值,返回一個布爾值

斷言目標值能夠讓給定的測試器返回真值

expect(1).to.satisfy(function (num) { return num > 0 })

.closeTo(expected, delta)

expect:Numbre,期望值

delta:Numbre,範圍半徑

斷言目標數字等於expected,或在期望值的+/-delta範圍內

expect(1.5).to.be.closeTo(1, 0.5)

.members(set)

set:Array

斷言目標是set的超集,或前者有後者所有嚴格相等(===)的成員。另外,如果設定了deep標記,則成員進行深度比較(include/contains只能接受單個值,但它們的主語除了是數組,還可以判斷字串;members則將它們的能力擴充為能夠接受一個數組,但主語只能是數組)

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

斷言目標值出現在list數組的某個頂層位置(直接子項目,嚴格相等)

expect('a').to.be.oneOf(['a', 'b', 'c'])expect(9).to.not.be.oneOf(['z'])// 嚴格相等,所以對象類的值必須為同一個引用才能被判定為相等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)

  1. object:Object,對象
  2. property:String,屬性名稱

斷言目標方法會改變指定對象的指定屬性

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)

  1. object:Object,對象
  2. property:String,屬性名稱

斷言目標方法會增加指定對象的屬性

var obj = { val: 10 }var fn = function () { obj.val = 15 }expect(fn).to.increase(obj, val)

.decrease(object, property)

  1. object:Object,對象
  2. property:String,屬性名稱

斷言目標方法會減少指定對象的屬性

var obj = { val: 10 }var fn = function () { obj.val = 5 }expect(fn).to.decrease(obj, val)

.extensible

斷言目標對象是可擴充的(可以添加新的屬性)

var nonExtensibleObject = Object.preventExtensions({})var sealedObject = Object.seal({})var frozenObject = Object.freeze({})expect({}).to.be.extensibleexpect(nonExtensibleObject).to.not.be.extensibleexpect(sealObject).to.not.be.extensibleexpect(frozenObject).to.not.be.extensible

.sealed

斷言目標對象是封閉的(無法添加新的屬性並且存在的屬性不能被刪除但可以被修改)

var sealedObject= Object.seal({})var frozenObject = Object.freeze({})expect(sealedObject).to.be.sealedexpect(frozenObject).to.be.sealedexpect({}).to.not.be.sealed

.frozen

斷言目標對象是凍結的(無法添加新的屬性並且存在的屬性不能被刪除和修改)

var frozenObject = Object.freeze({})expect(frozenObject).to.be.frozenexpect({}).to.not.be.frozen

TDD

除了一些文法糖以外,Chai提供的assert風格的斷言和node.js包含的assert模組非常相似。assert風格是三種斷言風格中唯一不支援鏈式調用的。

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援幫客之家。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.