迁移指南
从 Jest 迁移
Vitest 在设计时就考虑了与 Jest 兼容的 API,以便尽可能简化从 Jest 的迁移。尽管如此,您可能仍然会遇到以下差异:
全局变量作为默认值
Jest 默认启用了其 全局 API。Vitest 则默认不启用。您可以通过 globals
配置项 启用全局变量,或者更新代码,改为从 vitest
模块导入所需内容。
如果您选择保持禁用全局变量,请注意,诸如 testing-library
这样的常用库将无法自动执行 DOM 清理。
模块模拟
在 Jest 中,模拟模块时,工厂函数的返回值即为默认导出。而在 Vitest 中,工厂函数需要返回一个对象,该对象显式地定义了所有导出。例如,以下 jest.mock
需要按如下方式更新:
- jest.mock('./some-path', () => 'hello')
+ vi.mock('./some-path', () => ({
+ default: 'hello',
+ })
有关更多详细信息,请参阅 vi.mock
API 部分。
自动模拟行为
与 Jest 不同,<root>/__mocks__
中的模拟模块只有在调用 vi.mock()
时才会被加载。如果需要在每个测试中都模拟这些模块(如同在 Jest 中),可以在 setupFiles
中进行模拟。
导入模拟包的原始版本
如果您只需要部分模拟某个包,之前可能使用过 Jest 的 requireActual
函数。在 Vitest 中,您应该将这些调用替换为 vi.importActual
。
- const { cloneDeep } = jest.requireActual('lodash/cloneDeep')
+ const { cloneDeep } = await vi.importActual('lodash/cloneDeep')
环境变量
与 Jest 一样,如果之前未设置,Vitest 会将 NODE_ENV
设置为 test
。Vitest 中与 JEST_WORKER_ID
对应的变量是 VITEST_POOL_ID
(始终小于或等于 maxThreads
)。如果您依赖 JEST_WORKER_ID
,请记得将其重命名为 VITEST_POOL_ID
。Vitest 还公开了 VITEST_WORKER_ID
,它是运行中工作线程的唯一 ID——此数字不受 maxThreads
的影响,并且会随着每个创建的工作线程而增加。
如果您需要修改环境变量,在 Jest 中可以使用 replaceProperty API,而在 Vitest 中,可以使用 vi.stubEnv 实现相同的功能。
Done 回调
从 Vitest v0.10.0 开始,测试的回调写法已被弃用。您可以重写它们以使用 async
/await
函数,或使用 Promise 模拟回调。
- it('should work', (done) => {
+ it('should work', () => new Promise(done => {
// ...
done()
- })
+ }))
钩子函数
在 Vitest 中,beforeAll
/beforeEach
钩子函数可以返回 清理函数。因此,如果您的钩子函数返回的不是 undefined
或 null
,可能需要重写这些钩子函数的声明。
- beforeEach(() => setActivePinia(createTestingPinia()))
+ beforeEach(() => { setActivePinia(createTestingPinia()) })
类型
Vitest 的 Vi
命名空间中没有公开很多类型,该命名空间主要用于与匹配器保持兼容。因此,您可能需要直接从 vitest
导入所需的类型,而不是依赖 Vi
命名空间。
- let fn: jest.Mock<string, [string]>
+ import type { Mock } from 'vitest'
+ let fn: Mock<[string], string>
此外,如代码差异所示,Vitest 使用 Args
类型作为第一个参数,而非 Returns
。
定时器
Vitest 不支持 Jest 的旧式定时器。
Vue 快照
这不是 Jest 特有的功能,但如果您之前使用 Jest 和 vue-cli 预设,您需要安装 jest-serializer-vue
包,并在 setupFiles 中使用它:
vite.config.js
import { defineConfig } from 'vite';
export default defineConfig({
test: {
setupFiles: ['./tests/unit/setup.js'],
},
});
tests/unit/setup.js
import vueSnapshotSerializer from 'jest-serializer-vue';
expect.addSnapshotSerializer(vueSnapshotSerializer);
否则,您的快照中会包含大量转义的 "
字符。