0%

vitest的使用(三)

断言常用方法

断言最核心的方法就是expect和后面的toXXXvitest根据js不同的数据结构类型,有不同的断言方法

万能toBe

  1. 用于判断基本类型是否相等,对象的引用是否相等
  2. 相当于调用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属性

  1. not属性将否定该断言
  2. 如果断言相等会抛出错误,测试失败
1
2
3
it('test not toBe', () => {
expect(1).not.toBe(2)
})

基本数据类型断言

大部基本数据类型都可以使用toBe来断言也可以使用特定的方法

数字比较大小

  1. toBeGreaterThan大于预期结果
  2. toBeLessThan小于预期结果
  3. toBeGreaterThanOrEqual大于等于预期结果
  4. 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)
// not
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) //测试失败,0.2+0.3 is 0.30000000004
})
it('test toBeColseTo', () => {
expect(0.2 + 0.1).not.toBe(0.3) //测试成功
expect(0.2 + 0.1).toBeCloseTo(0.3) //测试成功
})

判断未定义

  1. toBeDefined断言值不等于undefined
  2. toBeUndefined断言值等于undefined
1
2
3
4
5
6
7
it('test undefined', () => {
//undefined
expect(undefined).toBe(undefined) // toBe方式
expect(undefined).not.toBeDefined()
expect(undefined).toBeUndefined()
expect('').toBeDefined() //''不等于undefined表示已经定义了
})

判断转换的true和false

  1. toBeTruthy断言xxx可以通过!!xxx转换为true
  2. toBeFalsy断言xxx可以通过!!xxx转换为false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
it('test Boolean ', () => {
// boolean true
expect(!!2).toBe(true) // toBe 替代方式
expect(true).toBeTruthy()
expect(1).toBeTruthy()
expect({}).toBeTruthy()
expect([]).toBeTruthy()

// boolean false
expect(!!'').toBe(false) // toBe 替代方式
expect(0).toBeFalsy()
expect('').toBeFalsy()
expect(null).toBeFalsy()
expect(undefined).toBeFalsy()
expect(Number.NaN).toBeFalsy()
expect(false).toBeFalsy()
})

判断是否为null

  1. 通过toBeNull断言某些内容是否为null
1
2
3
4
it('test null', () => {
expect(null === null).toBe(true) // toBe替代方式
expect(null).toBeNull()
})

引用类型断言

  1. toEqual断言判断实际值是否等于接收的值

    • 如果它是一个对象,则看是否有相同的结构(递归比较)
    • 如果对象某个属性为undefined时会自动忽略
  2. 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' })
    })
  3. toContain断言实际值是否在数组(类数组也可以)中或者字符串中

    1
    2
    3
    4
    5
    6
    it('test toContain', () => {
    expect(['apple', 'orange']).toContain('orange')
    expect('123abc123').toContain('123abc')
    // const element = document.querySelector('#el')
    // expect(document.querySelector('#wrapper')).toContain(element)
    })
  4. toHaveProperty断言对象是否具有提供的引用key处的属性

    1
    2
    3
    it('test toHaveProperty', () => {
    expect({ name: 'xxx', age: 10 }).toHaveProperty('name')
    })
  5. 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断言

  1. toThrow捕获错误的断言方法,在抛出错误的场景会用到

    1
    2
    3
    4
    5
    it('test Error ', () => {
    expect(() => {
    JSON.parse('{')
    }).toThrow()
    })

快照断言

什么是快照

  1. 快照就是将对象的结构转换成字符串然后存放起来
  2. 当代码改变了后可能会导致输出的内容和快照不匹配就会测试失败
  3. 快照其实是一种偷懒的方式,通过快照可以快速反馈问题

快照的断言方法

  1. toMatchInlineSnapshot
    • 用于行内快照断言
    • 适合小范围,少量的数据结构存储
  2. 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()
})

函数断言

  1. toHaveBeenCalled判断函数是否被调用
  2. toHaveBeenCalledTimes判断函数被调用次数
  3. 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) {
//...
}
}
// 先用vi.spyOn方法调用
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()