自定义断言辅助函数
可复用的断言辅助函数能让测试更易读,但代价是堆栈跟踪信息会受影响。当某个辅助函数内部的断言失败时,跟踪信息会指向辅助函数内部的那一行,而不是调用它的测试。对于在许多测试中共用同一个辅助函数的情况,仅凭堆栈跟踪并不能识别到底是哪个调用点失败了。
vi.defineHelper 4.1.0+ 会包装一个函数,使 Vitest 将其内部实现从堆栈中剥离,并把错误指回到调用点。
模式
ts
import { expect, test, vi } from 'vitest'
const assertPair = vi.defineHelper((a: unknown, b: unknown) => {
expect(a).toEqual(b) // ❌ 失败不会指向这里
})
test('example', () => {
assertPair('left', 'right') // ✅ 失败会指向这里
})当 assertPair 失败时,差异和堆栈帧会显示测试中调用它的那一行。这与内置 matcher 提供的行为相同。
组合多个期望
同样的包装器也适用于封装多个断言的辅助函数:
ts
import { expect, test, vi } from 'vitest'
const expectValidUser = vi.defineHelper((user: unknown) => {
expect(user).toHaveProperty('id')
expect(user).toHaveProperty('email')
expect(user.email).toMatch(/@/)
})
test('返回一个有效用户', async () => {
const user = await fetchUser('alice')
expectValidUser(user)
})任何一个内部 expect 调用失败,都会被报告到测试中的 expectValidUser(user) 那一行。
只要一个可复用的检查会多次调用 expect,就应该使用 defineHelper,无论它是像 expectValidJWT 这样的领域特定辅助函数,还是任何原本会直接内联到每个测试中的 expect 代码块。
关于附加到 expect.extend 的非对称 matcher 和自定义 matcher,请参见扩展 Matcher。
