You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 16:12:49