扩展匹配器
Vitest 兼容 Chai 和 Jest,因此你可以选择使用 chai.use API 或 expect.extend 来扩展匹配器。
本指南将详细介绍如何使用 expect.extend 扩展匹配器。如果你对 Chai 的 API 感兴趣,请查阅他们的指南。
要扩展默认匹配器,请调用 expect.extend 并传入一个包含你的匹配器函数的对象。
expect.extend({
toBeFoo(received, expected) {
const { isNot } = this;
return {
// 不要根据 isNot 修改 'pass' 属性的值。Vitest 会自动处理。
pass: received === 'foo',
message: () => `${received} is${isNot ? ' not' : ''} foo`,
};
},
});如果你正在使用 TypeScript,可以在环境声明文件(例如:vitest.d.ts)中使用以下代码扩展默认的 Assertion 接口:
import 'vitest';
interface CustomMatchers<R = unknown> {
toBeFoo: () => R;
}
declare module 'vitest' {
interface Matchers<T = any> extends CustomMatchers<T> {}
}import 'vitest';
interface CustomMatchers<R = unknown> {
toBeFoo: () => R;
}
declare module 'vitest' {
interface Assertion<T = any> extends CustomMatchers<T> {}
interface AsymmetricMatchersContaining extends CustomMatchers {}
}TIP
自 Vitest 3.2 起,你可以扩展 Matchers 接口,以便在 expect.extend、expect().* 和 expect.* 方法中同时实现类型安全的断言。在此之前,你需要分别为它们定义独立的接口。
WARNING
请确保在你的 tsconfig.json 中包含环境声明文件。
匹配器的返回值应与以下接口兼容:
interface ExpectationResult {
pass: boolean;
message: () => string;
// 如果你提供了这些属性,当匹配器不通过时,它们会自动显示在差异报告中,
// 因此你无需手动打印差异。
actual?: unknown;
expected?: unknown;
}WARNING
如果你创建了一个异步匹配器,请务必在测试中 await 其结果(例如:await expect('foo').toBeFoo()):
expect.extend({
async toBeAsyncAssertion() {
// ...
},
});
await expect().toBeAsyncAssertion();匹配器函数的第一个参数是接收到的值(即 expect(received) 中的 received)。其余参数则直接传递给匹配器。
匹配器函数可以通过 this 上下文访问以下属性:
isNot
如果匹配器是通过 not 修饰符调用的(例如:expect(received).not.toBeFoo()),则返回 true。
promise
如果匹配器是通过 resolved 或 rejected 修饰符调用的,此值将包含该修饰符的名称。否则,它将是一个空字符串。
equals
这是一个用于比较两个值的工具函数。如果两个值相等,则返回 true;否则返回 false。此函数是大多数匹配器内部使用的工具,默认支持包含非对称匹配器的对象比较。
utils
这里包含一组实用函数,可用于显示消息。
this 上下文还包含有关当前测试的信息。你也可以通过调用 expect.getState() 来获取这些信息。最有用的属性是:
currentTestName
当前测试的完整名称(包含 describe 块的名称)。
testPath
当前测试文件的路径。