Vitest全局单元测试Mock配置问题求助
Vitest setupFiles 复用全局Mock失败的解决方案
问题背景
已在单个测试文件my.test.ts中成功配置Mock:
// THIS IS WORKING WITHOUT ANY ISSUES vi.mock("./getCashedDatasapceToken", () => { return { getCashedDatasapceToken: () => { return { access_token: getTokenResponse.access_token, expires_in: "2030-03-20", }; }, }; }); describe("fetchAutocompleteSuggestions", () => { it("should return autocomplete suggestions for searchText = 'online'", async () => { const response = await fetchAutocompleteSuggestions("online"); expect(response).toEqual(fetchAutocompleteResponse); }); });
尝试通过setupFiles在全局复用该Mock,但配置后未生效,相关配置如下:
vitest.config.ts
export default defineConfig({ test: { globals: true, setupFiles: ["tests-config/setup-tests.ts"], }, resolve: { alias: { "@": path.resolve(__dirname, "./src"), }, }, });
setup-tests.ts
beforeEach(() => { vi.mock("./getCashedDatasapceToken", () => { return { getCashedDatasapceToken: () => { return { access_token: getTokenResponse.access_token, expires_in: "2030-03-20", }; }, }; }); }); beforeAll(() => server.listen()); afterEach(() => { server.resetHandlers(); vi.restoreAllMocks(); }); afterAll(() => server.close());
核心问题与修复步骤
1. vi.mock 不能放在钩子函数内
Vitest的vi.mock采用静态分析机制,会在测试文件执行前优先处理所有vi.mock调用,无论它被包裹在beforeEach/beforeAll等钩子中。因此必须将vi.mock放在模块顶层,不能嵌套在钩子函数里。
2. 修正模块路径
setup文件的执行上下文是项目根目录,原代码中的相对路径./getCashedDatasapceToken会指向根目录下的文件,而非src目录。建议使用配置好的别名@或者绝对路径:
3. 避免清除全局Mock
vi.restoreAllMocks()会清除所有mock的实现,导致全局配置的Mock失效。如果需要重置mock的调用记录,改用vi.resetAllMocks();如果不需要恢复全局Mock,直接移除该语句。
修正后的setup-tests.ts
// setup-tests.ts // 直接在模块顶层调用vi.mock import path from 'path'; // 方式1:使用别名(确保setup文件能识别@别名) vi.mock("@/getCashedDatasapceToken", () => { return { getCashedDatasapceToken: () => { return { access_token: getTokenResponse.access_token, expires_in: "2030-03-20", }; }, }; }); // 方式2:使用绝对路径(避免别名识别问题) // vi.mock(path.resolve(__dirname, '../src/getCashedDatasapceToken'), () => { // return { // getCashedDatasapceToken: () => { // return { // access_token: getTokenResponse.access_token, // expires_in: "2030-03-20", // }; // }, // }; // }); beforeAll(() => server.listen()); afterEach(() => { server.resetHandlers(); // 改用resetAllMocks重置调用记录,而非清除mock实现 vi.resetAllMocks(); }); afterAll(() => server.close());
额外注意事项
- 确保
getTokenResponse在setup文件中可访问:如果该变量定义在测试文件中,需提取到共享的工具文件(如tests-config/utils.ts)并导入到setup-tests.ts中。 - 验证setup文件路径:确认
setupFiles配置的路径相对于项目根目录是正确的。
内容的提问来源于stack exchange,提问作者Jacek Kacperski
相关产品推荐
相关产品推荐

