断言常用方法
断言最核心的方法就是expect
和后面的toXXX
,vitest
根据js
不同的数据结构类型,有不同的断言方法
万能toBe
- 用于判断基本类型是否相等,对象的引用是否相等
- 相当于调用
Object.is
方法
1 2 3 4 5 6 7 8 9 10 11
| it('test toBe ', () => { const stock = { type: 'apples', count: 13 }
expect(stock.type).toBe('apples') expect(stock.count).toBe(13) const refStock = stock expect(stock).toBe(refStock) })
|
not属性
not
属性将否定该断言- 如果断言相等会抛出错误,测试失败
1 2 3
| it('test not toBe', () => { expect(1).not.toBe(2) })
|
基本数据类型断言
大部基本数据类型都可以使用toBe
来断言也可以使用特定的方法
数字比较大小
toBeGreaterThan
大于预期结果toBeLessThan
小于预期结果toBeGreaterThanOrEqual
大于等于预期结果toBeLessThanOrEqual
小于等于预期结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| it('test 数字 ', () => { expect(10 + 10).toBe(20) expect(10 + 10).not.toBe(30) expect(3).toBeGreaterThan(2) expect(3).toBeLessThan(4) expect(3 < 4).toBe(true)
expect(3).toBeGreaterThanOrEqual(3) expect(3).toBeGreaterThanOrEqual(2) expect(3 >= 3).toBe(true) expect(3 >= 2).toBe(true) expect(3).toBeLessThanOrEqual(3) expect(3).toBeLessThanOrEqual(4) expect(3 <= 3).toBe(true) expect(3 <= 4).toBe(true) })
|
浮点数比较
浮动数不能直接用expect(0.2+0.1).toBe(0.3)
,因为精度问题,必须使用toBeCloseTo
1 2 3 4 5 6 7
| it.fails('test toBeCloseTo', () => { expect(0.2 + 0.1).not.toBe(0.3) }) it('test toBeColseTo', () => { expect(0.2 + 0.1).not.toBe(0.3) expect(0.2 + 0.1).toBeCloseTo(0.3) })
|
判断未定义
toBeDefined
断言值不等于undefined
toBeUndefined
断言值等于undefined
1 2 3 4 5 6 7
| it('test undefined', () => { expect(undefined).toBe(undefined) expect(undefined).not.toBeDefined() expect(undefined).toBeUndefined() expect('').toBeDefined() })
|
判断转换的true和false
toBeTruthy
断言xxx
可以通过!!xxx
转换为true
toBeFalsy
断言xxx
可以通过!!xxx
转换为false
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| it('test Boolean ', () => { expect(!!2).toBe(true) expect(true).toBeTruthy() expect(1).toBeTruthy() expect({}).toBeTruthy() expect([]).toBeTruthy()
expect(!!'').toBe(false) expect(0).toBeFalsy() expect('').toBeFalsy() expect(null).toBeFalsy() expect(undefined).toBeFalsy() expect(Number.NaN).toBeFalsy() expect(false).toBeFalsy() })
|
判断是否为null
- 通过
toBeNull
断言某些内容是否为null
1 2 3 4
| it('test null', () => { expect(null === null).toBe(true) expect(null).toBeNull() })
|
引用类型断言
toEqual
断言判断实际值是否等于接收的值
- 如果它是一个对象,则看是否有相同的结构(递归比较)
- 如果对象某个属性为
undefined
时会自动忽略
toStrictEqual
是更严格的toEqual
- 会检查具有
undefined
属性的键,{a:undefined,b:2}
和{b:2}
不匹配 - 会检查数组稀疏性,
[,1]
与[undefined,1]
不匹配 - 会检查对象类型,具有相同字段的
a
,b
的类实例和具有相同字段a
,b
普通对象不相等
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| it('test toEqual', () => { const stockBill = { type: 'apples', count: 13 } const stockMary = { type: 'apples', count: 13 } const stockBill2 = { type: 'apples', count: 13, name: undefined } const stockMary2 = { type: 'apples', count: 13 } expect(stockBill).toEqual(stockMary) expect(stockBill).not.toBe(stockMary)
expect(stockBill2).toEqual(stockMary2) expect(stockBill2).not.toBe(stockMary2) })
it('test toStrictEqual', () => { const stockBill = { type: 'apples', count: 13, name: undefined } const stockMary = { type: 'apples', count: 13 } class Stock { type: any constructor(type: any) { this.type = type } } expect(stockBill).not.toStrictEqual(stockMary) expect([1]).not.toStrictEqual([undefined, 1]) expect(new Stock('apples')).not.toStrictEqual({ type: 'apples' }) })
|
toContain
断言实际值是否在数组(类数组也可以)中或者字符串中
1 2 3 4 5 6
| it('test toContain', () => { expect(['apple', 'orange']).toContain('orange') expect('123abc123').toContain('123abc') })
|
toHaveProperty
断言对象是否具有提供的引用key
处的属性
1 2 3
| it('test toHaveProperty', () => { expect({ name: 'xxx', age: 10 }).toHaveProperty('name') })
|
toMatchObject
断言对象是否匹配另一个对象的部分属性。
expect
的对象要完全包含toMatchObject
的对象的属性和值- 从最外层开始比较,外层都不匹配就直接失败
1 2 3 4 5 6 7
| it('test toMatchObject', () => { expect([{ foo: 'bar' }, { baz: 1 }]).toMatchObject([{ foo: 'bar' }, { baz: 1 }]) expect({ obj: { name: 'xxx' }, height: 10 }).toMatchObject({ height: 10 }) expect({ obj: { name: 'xxx' }, height: 10 }).not.toMatchObject({ name: 'xxx' }) })
|
Error断言
toThrow
捕获错误的断言方法,在抛出错误的场景会用到
1 2 3 4 5
| it('test Error ', () => { expect(() => { JSON.parse('{') }).toThrow() })
|
快照断言
什么是快照
- 快照就是将对象的结构转换成字符串然后存放起来
- 当代码改变了后可能会导致输出的内容和快照不匹配就会测试失败
- 快照其实是一种偷懒的方式,通过快照可以快速反馈问题
快照的断言方法
toMatchInlineSnapshot
toMatchSnapshot
- 会生成一个文件,它适合一些大型的,长久不变更的地方
- 可以对配置文件进行快照,或者远程图标库
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
| it('test toMatchInlineSnapshot', () => { const data = { foo: new Set(['bar', 'snapshot']) } expect(data).toMatchInlineSnapshot(` { "foo": Set { "bar", "snapshot", }, } `) expect(22).toMatchInlineSnapshot('22') expect(true).toMatchInlineSnapshot('true') expect([1, 2, 3]).toMatchInlineSnapshot(`[ 1, 2, 3, ]`) expect({ name: 'xxx' }).toMatchInlineSnapshot(`{ "name": "xxx", }`) }) it('test toMatchSnapshot', () => { const config = { url: 'url', domain: 'domain', analysis: 'analysis alias' } expect(config).toMatchSnapshot() })
|
函数断言
toHaveBeenCalled
判断函数是否被调用toHaveBeenCalledTimes
判断函数被调用次数toHaveBeenCalledWith
判断函数被调用的时候传递了什么参数
注意:使用vi.spyOn
方法对原函数进行调用再进行断言
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| it('test function', () => { const market = { buy(subject: string, amount: number) { } } const buySpy = vi.spyOn(market, 'buy') expect(buySpy).not.toHaveBeenCalled() market.buy('apples', 10) market.buy('apples', 10) expect(buySpy).toHaveBeenCalled() expect(buySpy).toHaveBeenTimes(2) expect(buySpy).toHaveBeenCalledWith('apples', 10) })
|
也可以使用vi.fn
创建一个假函数来测试
1 2 3 4 5
| const mockFunction = vi.fn() mockFunction() expect(mockFunction).toHaveBeenCalled() expect(mockFunction).toHaveBeenTimes(1) expect(mockFunction).toHaveBeenCalledWith()
|