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

如何解决Jest和VITest中‘Cannot access 'mockKeycloak' before initialization’错误

解决Vitest中mock变量初始化顺序导致的"Cannot access 'mockKeycloak' before initialization"错误

问题原因

你遇到的错误核心是Vitest会把所有vi.mock调用自动提升到文件最顶部执行,不管代码书写顺序。你的代码里存在三个问题:一是重复调用了vi.mock("keycloak-js"),二是用let和const重复声明了同名变量mockKeycloak,最关键的是:带工厂函数的vi.mock被提升执行时,后面的const mockKeycloak还没完成初始化,工厂函数引用它就触发了暂时性死区错误。

解决方案

下面给出两种可行的修正方式:

方法1:将mock对象直接内嵌到mock工厂函数中

完全避免外部变量依赖,是最稳妥的写法:

// Import statements...

vi.mock("keycloak-js", () => {
  return {
    __esModule: true,
    default: vi.fn().mockImplementation(() => ({
      init: vi.fn(() => Promise.resolve()),
      updateToken: vi.fn(() => Promise.resolve()),
      createLoginUrl: vi.fn(() => "mock-login-url"),
      token: "mock-token",
      authServerUrl: "mock-auth-url",
      realm: "mock-realm",
    })),
  };
});

// Other mock setups...

describe("My Test Suite", () => {
  beforeEach(async () => {
    // ... Initialization code ...
  });

  test("My test case", async () => {
    // ... Test logic ...
  });
});

方法2:用let声明并提前赋值,复用mock对象

如果需要在测试其他环节复用这个mock对象,可以用let声明并提前完成赋值,避免暂时性死区问题:

// Import statements...

// 用let声明并直接赋值,跳过暂时性死区
let mockKeycloak = {
  init: vi.fn(() => Promise.resolve()),
  updateToken: vi.fn(() => Promise.resolve()),
  createLoginUrl: vi.fn(() => "mock-login-url"),
  token: "mock-token",
  authServerUrl: "mock-auth-url",
  realm: "mock-realm",
};

// 移除多余的vi.mock调用,只保留带工厂函数的版本
vi.mock("keycloak-js", () => {
  return {
    __esModule: true,
    default: vi.fn().mockImplementation(() => mockKeycloak),
  };
});

// Other mock setups...

describe("My Test Suite", () => {
  beforeEach(async () => {
    // 可在此处重置mock函数状态,避免测试用例间污染
    mockKeycloak.init.mockResolvedValue(true);
    mockKeycloak.updateToken.mockResolvedValue(true);
  });

  test("My test case", async () => {
    // ... Test logic ...
  });
});

额外注意事项

  • 不要重复mock同一个模块,多次调用vi.mock("keycloak-js")会导致配置冲突
  • 如果需要动态修改mock行为(比如不同测试用例返回不同值),可以使用vi.doMock(它不会被自动提升,执行顺序与代码书写顺序一致),但常规场景下上面两种方法足够覆盖需求

内容的提问来源于stack exchange,提问作者CoolLife

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 03:58:40