Vitest使用别名路径模块Mock失败:实际函数被调用而非Mock
Vitest 别名模块 Mock 失效问题解决方法
核心原因
Vitest 对别名路径的模块拦截逻辑需要严格匹配导入路径与配置的别名,若别名配置未同步或模块缓存干扰,会导致 Mock 无法替换实际函数。
具体解决步骤
1. 同步 TSConfig 与 Vitest 的别名配置
确保 Vitest 能正确识别并解析别名路径,推荐使用 vite-tsconfig-paths 插件自动同步:
tsconfig.json 配置:
{ "compilerOptions": { "baseUrl": ".", "paths": { "@mypackage/*": ["src/*"] } } }
vitest.config.ts 配置:
import { defineConfig } from 'vitest/config'; import tsconfigPaths from 'vite-tsconfig-paths'; export default defineConfig({ plugins: [tsconfigPaths()], // 自动读取tsconfig的paths配置 test: { // 开启测试隔离,避免模块缓存干扰 isolate: true } });
2. 严格匹配别名路径进行 Mock
测试中使用与业务代码完全一致的别名路径调用 vi.mock:
// 业务代码中导入:import { asyncFuncA } from '@mypackage/utils' // 测试文件中Mock写法: vi.mock('@mypackage/utils', () => ({ asyncFuncA: vi.fn().mockResolvedValue('模拟返回值') })); // 测试用例 test('asyncFuncB 应调用 Mock 的 asyncFuncA', async () => { const { asyncFuncB } = await import('@mypackage/core'); await asyncFuncB(); expect(asyncFuncA).toHaveBeenCalled(); });
3. 清除模块缓存避免干扰
如果之前用相对路径测试过,模块可能被缓存,可在测试文件开头重置模块:
vi.resetModules(); // 重置所有已加载的模块,确保Mock生效
4. 验证别名解析路径是否正确
打印别名对应的实际文件路径,确认解析是否正确:
import * as utils from '@mypackage/utils'; console.log(require.resolve('@mypackage/utils')); // 输出实际文件路径,检查是否与预期一致
5. 兜底方案:手动映射到实际文件路径
若上述方法无效,可直接使用相对路径(基于测试文件位置)进行 Mock:
import { join } from 'node:path'; import { fileURLToPath } from 'node:url'; const utilsPath = join(fileURLToPath(new URL('../src/utils', import.meta.url))); vi.mock(utilsPath, () => ({ asyncFuncA: vi.fn().mockResolvedValue('模拟返回值') }));
内容的提问来源于stack exchange,提问作者loicb
相关产品推荐
相关产品推荐

