使用Vitest模拟依赖问题求助:原Jest可用代码失效
Vitest 依赖模拟实用方案
以下是针对从Jest切换到Vitest后依赖模拟失效问题的常见解决方法:
- 基础模块模拟
Vitest 使用vi.mock()替代 Jest 的jest.mock(),语法逻辑相近但需注意适配Vitest的模块系统。比如模拟第三方库:
// 模拟axios的get请求返回固定数据 vi.mock('axios', () => ({ default: { get: vi.fn().mockResolvedValue({ data: '模拟返回数据' }) } }))
模拟本地文件时确保路径正确,ES模块和CommonJS环境下的写法保持和原代码一致。
- 部分方法替换(Spy)
如果只需替换模块中的单个方法而非整个模块,用vi.spyOn()实现:
import { priceCalculator } from './utils' test('测试价格计算方法', () => { // 替换calculate方法的返回值 const calculateSpy = vi.spyOn(priceCalculator, 'calculate').mockReturnValue(200) // 执行你的测试逻辑 expect(calculateSpy).toHaveBeenCalled() // 测试结束后恢复原方法,避免影响其他测试 calculateSpy.mockRestore() })
注意:vi.spyOn 默认不会覆盖原方法实现,必须手动调用 mockReturnValue 或 mockImplementation 来指定模拟行为。
- 兼容Jest的部分模拟逻辑
如果原Jest代码使用了jest.requireActual保留模块原有实现,Vitest 对应使用vi.importActual:
// 保留api模块的其他方法,仅模拟fetchData vi.mock('./api', async () => { const actualModule = await vi.importActual('./api') return { ...actualModule, fetchData: vi.fn().mockResolvedValue('模拟接口响应') } })
若遇到模块缓存导致的模拟失效,可在测试文件开头添加 vi.resetModules() 重置模块状态。
- 全局对象与环境变量模拟
针对依赖全局对象(如window、process)的代码,Vitest 提供直接模拟的方式:
// 模拟环境变量 vi.stubEnv('APP_ENV', 'test') // 模拟window上的全局方法 vi.stubGlobal('localStorage', { getItem: vi.fn().mockReturnValue('mock-storage-data') })
如果以上方法仍未解决问题,建议检查 vitest.config.ts 中的配置项,比如 test.mockReset 是否开启、test.globals 是否启用,这些配置会直接影响模拟的生效逻辑。
内容的提问来源于stack exchange,提问作者Carlos Oliveira
相关产品推荐
相关产品推荐

