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

Vitest中如何清除/重置Mock?useRoles测试遇Mock复用问题

解决Vitest中vi.mock在测试用例间无法重置的问题

你遇到的核心问题是:vi.mock是静态执行的——Vitest会在测试文件初始化阶段就处理所有vi.mock调用,运行时在it块内调用的vi.mock不会覆盖之前的mock配置。而vi.clearAllMocks()和vi.resetAllMocks()仅负责清除mock函数的调用记录、重置调用次数,无法修改vi.mock定义的模块实现逻辑。

下面提供两种可行的解决方案:

方案一:静态Mock + 动态修改返回值

先在测试文件顶部统一Mock目标模块,再在每个测试用例中动态设置Mock函数的返回值,这是最简洁常用的方案:

import { afterEach, expect, vi } from "vitest";
import useRoles from "./useRoles";
import { useStore } from "./store";

// 提前Mock整个store模块
vi.mock("./store");
// 类型断言(JS环境可省略),让代码识别Mock后的函数类型
const mockedUseStore = vi.mocked(useStore);

describe("useRoles", () => {
  afterEach(() => {
    // 清除Mock调用记录,避免用例间污染
    vi.clearAllMocks();
  });

  it("should verify values when is:Learner", () => {
    // 设置当前测试的Mock返回值
    mockedUseStore.mockReturnValue({
      state: {
        profile: {
          currentRole: "learner"
        },
      },
    });

    const { isLearner } = useRoles();
    expect(isLearner.value).toBeTruthy();
  });

  it("should verify values when is:!Learner", () => {
    mockedUseStore.mockReturnValue({
      state: {
        profile: {
          currentRole: "admin"
        },
      },
    });

    const { isLearner } = useRoles();
    expect(isLearner.value).toBeFalsy();
  });
});

方案二:使用vi.doMock + 重置模块缓存

如果需要在不同用例中完全替换模块的Mock实现,可以用vi.doMock(运行时Mock),配合vi.resetModules()清除模块缓存,再异步导入目标函数:

import { afterEach, expect, vi } from "vitest";

describe("useRoles", () => {
  afterEach(() => {
    // 重置模块缓存,确保每个用例重新加载模块
    vi.resetModules();
    vi.clearAllMocks();
  });

  it("should verify values when is:Learner", async () => {
    // 运行时Mock store模块
    vi.doMock("./store", () => ({
      useStore: () => ({
        state: {
          profile: {
            currentRole: "learner"
          },
        },
      }),
    }));

    // 异步导入useRoles,确保使用最新的Mock配置
    const useRoles = (await import("./useRoles")).default;
    const { isLearner } = useRoles();
    expect(isLearner.value).toBeTruthy();
  });

  it("should verify values when is:!Learner", async () => {
    vi.doMock("./store", () => ({
      useStore: () => ({
        state: {
          profile: {
            currentRole: "admin"
          },
        },
      }),
    }));

    const useRoles = (await import("./useRoles")).default;
    const { isLearner } = useRoles();
    expect(isLearner.value).toBeFalsy();
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 22:30:52