Chai

Chai介绍

Chai 是一个针对 Node.js 和浏览器的行为驱动测试和测试驱动测试的诊断库,可与任何 JavaScript 测试框架集成。
本文介绍的Chai下的expect/should风格属于BDD(行为驱动开发)
因为本身语法相对简单,所以本文是类似于api的中文文档,其中有许多不足,见谅。

正片开始

  • to
  • be
  • been
  • is
  • that
  • which
  • and
  • has
  • have
  • with
  • at
  • of
  • same
    以上仅做语义化用,无实际作用

具体api介绍

  • not
    对之后的断言取反
  • deep
    针对对象、数组等进行深层次的键值对判断
  • any
    keys一同使用时表示至少满足一项
  • all
    与keys一同使用时表示至少全部满足
  • a | an
    既可做链式调用也可做断言
  • include | contains
    是否包含指定的值 既可做链式调用也可做断言
  • nested
    用于在propertyinclude等用.语法获取深层次属性
  • ok
    真值
  • true
    true
  • false
    false
  • null
    null
  • undefined
    undefined
  • NaN
    NaN
  • exist
    非null 非undefined
  • finite
    NaNInfinity
  • empty
    判断值长度为0 [] '' {}
  • arguments
    是否为arguments对象
  • equal
    ===
  • eql
    相当于deepequal的简写
  • above
    大于
  • least
    大于等于
  • below
    小于
  • most
    小于等于
  • within
    区间内(数字)
  • instanceof
    是否为该实例
  • property
    是否拥有指定属性
  • ownProperty
    是否拥有自身的属性
  • ownPropertyDescriptor
    属性描述对象
  • length
    length属性
  • lengthOf
    是否为指定长度值
  • match
    是否匹配指定正则
  • string
    是否包含指定字符串
  • keys
    配合其他字段使用,是否包含或不包含指定的key
  • throw
    是否抛出指定错误或字符串或匹配指定错误信息
  • respondTo
    断言是否会响应一个方法
  • itself
    配合respondTo用来判断是否为自身的方法
  • satisfy
    返回一个函数且参数为目标值且返回值为boolean,用来指定是否通过检测
  • closeTo
    判断值是否在期望值接收范围内
  • members
    类似于containsinclude,但是能接收数组,主语只能是数组
  • oneOf
    判断值是否出现在指定数组中
  • change
    判断方法是否会改变指定对象的指定属性的值
  • increase
    判断方法是否会增加指定对象的属性的值
  • decrease
    判断方法是否会减少指定对象的属性的值
  • extensible
    判断指定值是否可扩展(可以添加新属性)
  • sealed
    判断指定值是否封闭(不可添加新属性、不可删除旧属性、可修改旧属性)
  • frozen
    判断值是否冻结(不可添加新属性、不可删除旧属性、不可修改旧属性)
  • own
    判断值是否拥有指定的属性,不包含上层属性
  • by
    配合descreaseincreasechange等来判断断言值是否发生变化在指定范围内
  • fail
    判断是否会失败
  • ordered
    配合members用于指定members参数数组的顺序与主语数组的顺序一致

.not
对之后的断言取反

1
2
3
4
expect({a: 1}).to.not.equal({ a: 1 })
expect({ a: 1 }).to.be.not.have.a.keys('b')
expect([100, 200]).to.be.not.lengthOf(3)
expect([1, 2]).to.be.length.not.within(-1, 1)

.deep
普通的对象或数组比较是比较它们的整体是否相等。
比如

1
2
3
4
5
6
expect({ a: 1 }).to.be.not.equal({ a: 1 })
expect([1, 2]).to.be.not.equal([1, 2])
expect({ a: 1 }).to.be.deep.equal({ a: 1 })
expect([1, 2]).to.be.deep.equal([1, 2])
expect({ a: { b: { c: 3 } } }).to.be.deep.equal({ a: { b: { c: 3 } } })
expect({ a: { b: 2 } }).to.have.nested.deep.property('a.b')

相当于是严格相等 ===

.any
keys使用时至少满足一项

1
2
expect([100, 200]).to.have.any.keys(0)
expect({ a: 100, b: 200 }).to.have.any.keys('a', 'b')

.all
any类似,但是至少满足所有项

1
2
3
4
expect([100, 200]).to.has.all.keys(0, 1)
expect([100, 200]).to.not.has.all.keys(0)
expect({ a: 100, b: 200 }).to.has.all.keys('a', 'b')
expect({ a: 1, b: 2, c: 3 }).to.not.has.all.keys('a', 'b')

需要注意的是,如上最后一条断言所示,当allkeys一同使用时,断言对象的key必须和keys完全一样才能通过

.a .an
既可以用做链式判断也可用于断言
用作判断时无实际作用,仅用于语义化
用做断言时用于判断值是否为某一类型
方法type a = (type: 'string' | 'object' | 'null' | 'undefined' | 'array' | 'number' | 'symbol' | 'error' | 'promise'/*还有别的类型...*/, errmsg?: string) => any

1
2
3
4
5
6
7
8
9
10
11
12
13
expect(100).to.be.a('number')
expect({ a: 100 }).to.has.a.property('a')
expect(Symbol()).to.be.a('symbol')
expect(new Error()).to.be.a('error')
//自定义类型
const object = {
[Symbol.toStringTag]: 'diyObj'
}
expect(object).to.be.a('diyObj')
//继续断言
expect(100).to.be.a('number').and.to.equal(100)
//自定义错误信息
expect(100).to.be.a('number', 'it is not impossible')
  • 可用于自定义类型进行判断,如上使用Symbol.toStringTag进行自定义类型定义
  • aan断言会返回断言的值,可以继续做链式调用继续做其他判断
  • aan 有可选的第二参数可以指定出错时的错误信息

.include .contains
用于判断断言值是否包含某个指定的值,但是只能指定一个值
includescontains contain 同义
既可以用做链式判断也可用于断言
方法 type include = (value: any, errmsg?: string) => any

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//字符串包含
expect('Daniel').to.be.include('iel')
//数组
expect([1, 2]).to.be.a('array').and.include(1)
//严格相等
expect([1, '2']).to.not.be.include(2)
//对象
expect({ a: 1, b: 2 }).to.be.include({ a: 1 })
//map值包含
expect(new Map([[1, 2], [3, 4]])).to.be.include(2)
//set值包含
expect(new Set([1, 2, 3])).to.be.include(3)
//深层次严格相等
expect({ a: { b: 2 } }).to.be.not.include({ a: { b: 2 } })
expect({ a: { b: 2 } }).to.be.deep.include({ a: { b: 2 } })
expect({ a: { b: 2 } }).to.be.nested.deep.include({ 'a.b': 2 })
//自定义断言错误信息
expect([1, 2]).to.be.not.include(3, 'it is not impossible')
//配合members链式调用
expect([1, 2, 3]).to.be.include.members([1, 2])
//配合keys
expect({ a: 1, b: 2, c: 3 }).to.be.include.any.keys('a', 'b')
expect({ a: 1, b: 2 }).to.be.include.all.keys('a', 'b')
//对象可以获取上层属性
Object.prototype.say = 'Daniel'
expect({}).to.be.include({ say: 'Daniel' }).but.not.own.include({ say: 'Daniel' })

.nested
用于在propertyinclude等用.语法获取深层次属性
有时候对于深层次的对象或数组无法直接判断该内容,可以通过nested来实现深层次的值获取

1
2
3
4
//深层次嵌套获取
expect({ a: { b: { c: 1 } } }).to.be.nested.have.a.property('a.b.c')
//转义
expect({ '.a': { '..b': { '[c]': 1 } } }).to.be.nested.have.a.property('\\.a.\\.\\.b.\\[c\\]')

.ok
表示真值,如true [] {}

1
2
3
4
expect([]).to.be.ok
expect({}).to.be.ok
//自定义错误信息
expect(false, 'it is not impossible').to.be.not.ok

一般情况下不太需要使用此属性
关于其他象征性的值直接使用对应的属性就可以

1
2
3
4
expect(0).to.be.equal(0)
expect(true).to.be.true
expect(null).to.be.null
expect(undefined).to.be.undefined

.true
同上表示真值,但不进行类型转换,所以只有true能通过

1
expect(true).to.be.true

false
true相反,表示假值,不进行类型转换

1
expect(false).to.be.false

.null
用于判断值是否为null

1
expect(false).to.be.false

.undefined
用于判断值是否为undefined

1
expect(undefined).to.be.undefined

.NaN
用于判断值是否为NaN

1
2
3
//不推荐使用这个方法比较字符串等,可以直接使用equal
//expect('Daniel').to.be.NaN
expect(100).to.be.not.NaN

.exist
用于判断值是否存在,即非null 且 非undefined

1
2
3
4
expect(100).to.be.exist
expect(null).to.be.not.exist
expect([]).to.be.exist
expect(undefined).to.be.not.exist

.finite
表示有限数组,即非NaN 且 非Infinity

1
2
3
expect(200).to.be.finite
expect(Infinity).to.be.not.finite
expect('Daniel').to.be.not.finite

.empty
判断值得长度是否为0

1
2
3
4
5
6
//字符串的长度
expect('').to.be.empty
//数组长度
expect([]).to.be.empty
//对象则是判断可枚举的属性的数量(Object.keys(obj).length)
expect({}).to.be.empty

.arguments
判断值是否为arguments对象

1
expect(arguments).to.be.arguments

.equal
判断值是否严格相等,相当于===
type equal = (value: any, errmsg?: string) => any

1
2
3
4
5
6
7
8
9
//比较值的相等
expect(1).to.be.equal(1)
//数组和对象则无法严格相等
expect([1, 2, 3]).to.be.not.equal([1, 2, 3])
//数组和对象比较可以用之前介绍的deep
expect([1, 2, 3]).to.be.deep.equal([1, 2, 3])
expect({ a: 1 }).to.be.deep.equal({ a: 1 })
//自定义错误提示信息
expect([1, 2]).to.be.not.equal([1, 2], 'it is not impossible')

.eql
可以当做是deepequal的组合
type eql = (value: any, errmsg?: string) => any

1
2
3
4
5
//数组对象等值内容相等
expect([1, 2, 3]).to.be.eql([1, 2, 3])
expect({ a: 1 }).to.be.eql({ a: 1 })
//继续断言
expect({ a: 1 }).to.be.eql({ a: 1 }).and.not.be.empty
  • 如上所例🌰,eql返回值本身,可以继续向后做断言

.above
判断值是否大于指定值
type above = (value: number, errmsg?: string) => any

1
2
expect(100).to.be.above(10)
expect(100).to.be.not.above(101)
  • 对于字符串,数组等长度的比较建议直接使用lengthOf

.least
判断值是否不小于(大于等于)指定值
type least = (value: number, errmsg?: string) => any

1
2
expect(100).to.be.least(100)
expect(100).to.be.least(99)

.below
判断值是否小于指定值
type below = (value: number, errmsg?: string) => any

1
2
expect(100).to.be.below(101)
expect(100).to.be.not.below(99)

.most
判断值是否不大于(小于等于)指定值
type most = (value: number, errmsg?: string) => any

1
2
expect(100).to.be.most(100)
expect(100).to.be.most(101)

.within
判断值是否在指定区间内
type within = (start: number, end: number, errmsg?: string) => any

1
2
3
4
//包含开始和结束
expect(100).to.be.within(0, 100)
expect('Daniel').to.have.a.lengthOf.within(0, 100)
expect([1, 2, 3]).to.have.a.lengthOf.within(0, 100)
  • 不推荐使用该方法,因为它能够实现的测试基本都可以通过equal或是lengthOf来实现
1
2
3
4
//使用equal和lengthOf实现测试
expect(100).to.be.equal(100)
expect('Daniel').to.have.a.lengthOf(6)
expect([1, 2, 3]).to.have.a.lengthOf(3)

.instanceof
判断值是否为指定值的实例
type instanceof = (constructor: object, errmsg?: string) => any

1
2
3
4
5
6
function Father() {}
const father = new Father()
expect(father).to.be.instanceof(Father)
expect([]).to.be.instanceof(Array)
expect(new Number(100)).to.be.instanceof(Number)
expect(new String('Daniel')).to.be.instanceof(String)

.property
判断值是否包含指定属性
type property = (key: string, value?: any, errmsg?: string) => any

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//简单判断是否拥有该属性
expect({ a: 1 }).to.be.have.a.property('a')
//并且判断是否为该值
expect({ a: 1 }).to.be.have.a.property('a', 1)
//针对深层次的值比较需要 deep 参与
expect({ a: { b: 1 } }).to.be.not.have.a.property('a', { b: 1 })
expect({ a: { b: 1 } }).to.be.have.a.deep.property('a', { b: 1 })
//配合 own 用于判断是否为当前所有的实例实行
expect({ a: 1 }).to.be.have.a.property('a')
expect({ a: 1 }).to.be.have.a.property('toString')
expect({ a: 1 }).to.be.have.a.own.property('a')
expect({ a: 1 }).to.be.not.have.a.own.property('toString')
//配合 nested 进行深层次的比较
expect({ a: { b: 2 } }).to.be.have.nested.deep.property('a.b', 2)

.own
判断值是否拥有指定的属性,不包含上层属性

1
2
3
4
5
//结合property使用
expect({ a: 1 }).to.be.have.own.property('a')
expect({ a: 1 }).to.be.not.have.own.property('toString')
//配合 deep 和 property进行深层次的比较
expect({ a: { b: 2 } }).to.be.have.own.deep.property('a', { b: 2 })

.ownProperty
判断是否为本身属性,相当于是 .own.property的结合
type ownProperty = (key: string, value?: any, errmsg?: string) => any

1
2
expect({ a: 1 }).to.be.have.own.property('a')
expect({ a: 1 }).to.be.have.ownProperty('a')

.ownPropertyDescriptor
类似于上面的方法,用于判断是否为本身的属性
但是它可以传递第二参数,表示该属性的描述对象,不知道什么是描述对象的自行百度
type ownPropertyDescriptor = (key: string, value?: { get?: (undifiend || () => any)=undefined, set?: (undefined || () => any)=undefined, configurable?: boolean=false, enumerable?: boolean=false, value?: any=undefined, writable?: boolean=false }, errmsg?: string) => any

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const object = {
name: 'Daniel'
}
const descriper = {
//是否可枚举
enumerable: true,
//值
//value: 'hello world',
//是否可写
//writable: false,
//是否可修改描述符对象
//注意如果设置为false,后续将无法再修改其描述对象
configurable: true,
//获取值拦截
//设置了拦截就不能设置writable和value
get() {
return 'I love China'
},
//设置值拦截
set() {
return this.value
}
}
Object.defineProperty(object, 'name', descriper)

expect(object).to.be.ownPropertyDescriptor('name')
expect(object).to.be.ownPropertyDescriptor('name', descriper)
//自定义错误
expect(object).to.be.ownPropertyDescriptor('name', descriper, 'it is impossible')

.lengthOf .length
判断值是否存在length属性且为指定值
方法 type lengthOf = (value: number, errmsg?: string) => any

1
2
3
expect([1, 2, 3]).to.be.lengthOf(3)
//用于链式调用,但是不推荐
expect([1, 2, 3]).to.have.a.lengthOf.below(1)

.match
判断值是否与指定正则匹配
和普通match方法一样,所以主语就是string
matches效果与match相同
type match = (reg: Regexp, errmsg?: string) => any

1
2
3
expect('Daniel').to.be.match(/^D.+l$/)
expect('2020-08-10').to.be.match(/^\d{4}-\d{2}-\d{2}$/)
expect('13456787654').to.be.match(/^1[^12]\d{9}$/)

.string
判断值是否包含指定的字符串
type string = (value: string, errmsg?: string) => any

1
2
3
4
expect('Daniel').to.be.have.a.string('iel')
expect('hello').to.be.not.have.a.string('world')
//必须是连续子串
expect('world').to.be.not.have.a.string('rd')

.keys
用于判断数组对象SetMap等是否包含相应的key
type keys = (...args: Array<string | number>) => any

1
2
3
4
5
6
7
8
9
10
11
12
//普通使用需要将所有key全部传入
expect({ a: 1 }).to.be.have.keys('a')
expect([1, 2]).to.be.have.keys('0', '1')
expect(new Set([1, 2])).to.be.have.keys(1, 2)
expect(new Map([[ 'a', 1 ]])).to.be.have.keys('a')
//配合all 和 any 使用
expect({ a: 1, b: 2 }).to.be.have.any.keys('a')
expect({ a: 1, b: 2 }).to.be.be.have.all.keys('a', 'b')
//包含
expect({ a: 1, b: 2, c: 3 }).to.be.include.keys('a', 'b')
//深层次比较
expect({ a: { b: { c: 3 } } }).to.be.have.deep.keys('a.b')

.throw
判断值是否抛出指定的错误、错误信息等。
.throw(errConstructor | string | reg) 是否抛出指定错误或字符串或匹配指定错误信息
type throw = (errorLike?: Error | Construcotr, errMsgMatcher?: string | Regexp, errmsg?: string) => any

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const errors = new TypeError('oops')
function error() { throw errors }
//当不确定会抛出哪一种错误时,直接不传参数
expect(error).to.be.throw()
//传递具体的错误类型
expect(error).to.be.throw(TypeError)
//传递错误实例
expect(error).to.be.throw(errors, 'oops')
//第二参数可为字符串,且表示为子串
expect(error).to.be.throw(errors, 'oop')
//也支持正则
expect(error).to.be.throw(TypeError, /.+/)
//可直接传递字符串表示抛出的错误内容
expect(error).to.be.throw('oop')
//同样支持正则
expect(error).to.be.throw(/^o.+s$/)
//断言后的主语更改为错误对象
errors.code = 404
expect(error).to.be.throw(errors).and.that.have.a.property('code', 404)

throwsThrow同义🙆

.respondTo
用于判断一个对象或构造函数是否有相关的方法
type respondTo = (methodName: string ,errmsg?: string) => any

1
2
3
4
5
6
7
8
9
10
function Father() {}
Father.prototype.sayFather = function() {}
Father.saySon = function() {}
//正常响应所有方法
expect(new Father()).to.be.respondTo('sayFather')
//实例无法获取超集静态属性
expect(new Father()).to.be.not.respondTo('saySon')
expect({}).to.be.respondTo('toString')
//添加itself只能响应自身的方法
expect(Father).to.be.itself.respondTo('saySon').but.not.respondTo('sayFather')

respondsTo与此方法同义

.itself
配合上述的respondTo方法判断值是否响应指定的方法,但是为自身的方法,不包含prototype上的方法
具体事例可以看上面的respondTo

.satisfy
接收一个函数作为参数,函数参数为断言目标值,返回值为boolean,判断是否通过断言

  • type satisfy = (method: (target: any) => boolean, errmsg?: string) => any
1
2
3
4
5
6
7
//目标值在[0, 100]内
expect(100).to.be.satisfy(function(target) {
return target >= 0 && target <= 100
})
expect(100).to.be.satisfies(function(target) {
return target >= 0 && target <= 100
})

satisfies与此方法同义

.closeTo
指定值(仅数字)是否在期望值的接收范围内
此方法与within的区别就是within接收的两个参数是上限和下限
closeTo的参数,第一参数为期望的中间值,第二参数为上下限(第一参数加减第二参数)

  • type closeTo = (expected: number, delta: number, errmsg?: string) => any
1
2
3
4
5
//指定值在[-90, 110]之间
expect(100).to.be.closeTo(10, 100)
//包含临界值
expect(110).to.be.closeTo(10, 100)
expect(-90).to.be.closeTo(10, 100)

虽然此方法可以用于判断值是否在一个区间内,但是直接使用equal进行相等判断一样可以

.members
类似于contains、include,但是接收参数为数组,主语只能是数组
type members = (target: Array<any>, errmsg?: string) => any

1
2
3
4
5
6
7
8
9
10
11
12
//主语必须为数组
expect([1, 2, 3]).to.be.have.members([1, 2, 3])
//非简单类型数组需配合deep
expect([ { a: 1 } ]).to.be.have.deep.members([ { a: 1 } ])
//配合orderd来强制数组顺序与主语一致
expect([ 1, 2, 3 ]).to.be.have.ordered.members([ 1, 2, 3 ])
//配合include链式调用可以对不必要的数组项不进行验证
expect([1, 2, 3]).to.be.include.members([ 1, 2 ])
//相对于验证不存在的数组项推荐使用include
expect([1]).to.be.not.include(2).and.not.include(3)
//复合使用
expect([ { a: 1 }, { b: 2 }, { c: 3 } ]).to.be.include.deep.ordered.members([ { a: 1 }, { b: 2 } ])

.oneOf
判断值是否出现在指定数组中
type oneOf = (list: Array<any>, errmsg?: string) => any

1
2
3
4
//断言值在指定数组中
expect(100).to.be.oneOf([1, 2, 100])
//推荐直接使用equal
expect(100).to.be.equal(100)

.change
判断方法是否会改变指定的值,主语接收的是一个改变判定对象的值的方法
可以把它当做是increasedecrease的结合
但是推荐直接使用上述两个方法
type change = (value: ((value: any) => any) | any, prop?: string, errmsg?: string) => any

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//普通值
let number = 0
let string = '0'
let array = [ 0 ]
let object = { 0: 0 }
function changeNumber() { number ++ }
function changeString() { string += 1 }
function changeArray() { array[0] = 1 }
function changeObject() { object[0] += 1 }

function getNumber() { return number }
function getString() { return string }

//普通值需要借助函数
//数字
expect(changeNumber).to.be.change(getNumber)
//字符串
expect(changeString).to.be.change(getString)
//复合值则需添加第二参数,改变的属性名
//数组
expect(changeArray).to.be.change(array, '0')
//对象
expect(changeObject).to.be.change(object, '0')

//结合by具体断言改变的范围
expect(changeNumber).to.be.change(getNumber).by(1)


.increase | .decrease
increase 判断方法是否会增加指定对象的属性或者普通值的值
decrease 判断方法是否会减少指定对象的属性或者普通值的值
const increase = (value: any, prop?: string, errmsg?: string)
const decrease = (value: any, prop?: string, errmsg?: string)
并且只能是数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//普通值
let number = 0
function increase() { number ++ }
function decrease() { number -- }
function get() { return number }
expect(increase).to.be.increase(get)
expect(decrease).to.be.decrease(get)

//对象
let obj = { a: 1 }
function objIncrease() { obj.a ++ }
function objDecrease() { obj.a -- }
expect(objIncrease).to.be.increase(obj, 'a')
expect(objDecrease).to.be.decrease(obj, 'a')

//数组
let arr = [1, 2, 3]
function arrayIncrease() { arr[0] += 2 }
function arrayDecrease() { arr[0] -= 2 }
expect(arrayIncrease).to.be.increase(arr, '0').by(2)
expect(arrayDecrease).to.be.decrease(arr, '0').by(2)

//通过by判断增加的幅度
expect(objIncrease).to.be.increase(obj, 'a').by(1)
expect(objDecrease).to.be.decrease(obj, 'a').by(1)

.extensible
判断指定值是否可扩展(不可以添加新属性)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let object = {
name: 'Daniel',
sayName: function() {
return this.name
}
}
//设置对象为不可扩展
Object.preventExtensions(object)
//可修改
console.log(object)
object.name = 'Mike'
console.log(object)
//可删除
console.log(object)
delete object.name
console.log(object)
//不可新增
console.log(object)
object.age = 18
console.log(object)

//使用
expect(object).to.be.extensible

.sealed
判断指定值是否封闭(不可添加新属性、不可删除旧属性、可修改旧属性)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
let object = {
name: 'Daniel',
sayName: function() {
return this.name
}
}
//设置对象为封闭
Object.seal(object)

//不可新增
console.log(object)
object.age = 18
console.log(object)

//可修改
console.log(object)
object.name = 'Mike'
console.log(object)

//不可删除
console.log(object)
delete object.name
console.log(object)

//使用
expect(object).to.be.sealed

.frozen
判断值是否冻结(不可添加新属性、不可删除旧属性、不可修改旧属性)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
let object = {
name: 'Daniel',
sayName: function() {
return this.name
}
}

//设置对象为冻结
Object.freeze(object)

//不可新增
console.log(object)
object.age = 18
console.log(object)

//不可修改
console.log(object)
object.name = 'Mike'
console.log(object)

//不可删除
console.log(object)
delete object.name
console.log(object)

//使用
expect(object).to.be.frozen

.by
配合descreaseincreasechange等来判断断言值是否发生变化在指定范围内
具体事例🌰可以直接查看上述三个方法的例子👆

.fail
判断是否会失败
有两种参数传递方式

  1. type fail = (message?: string) => any
  2. type fail = (actual: any, expected: any, message?: string, operator: string) => any
1
2
3
4
5
6
7
//以下均会出错
//直接使用
expect.fail()
expect.fail('it is error')
//值判断
expect.fail(1, 2, 'it is impossible')
expect.fail(1, 2, 'it is impossible', '>')

.ordered
配合members用于指定members参数数组的顺序与主语数组的顺序一致

1
2
3
//members参数必须按顺序
expect([1, 2, 3]).to.be.ordered.members([1, 2, 3])
expect([1, 2, 3]).to.be.not.ordered.members([2, 1, 3])

完结

😊
如果有什么不对的地方,请指出。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!