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

如何阻止Jest.mock提升,仅在单个单元测试中应用指定Mock?

解决Jest仅在单个测试中Mock导入组件的问题

由于jest.mock会被Jest自动提升到模块顶部,无论你把它写在describe还是test块内,所有测试都会共享这个Mock。要实现仅在指定测试中使用Mock,有两种可靠方案:

方案1:使用jest.doMock + 动态导入

jest.doMock不会被Jest提升,仅在调用位置生效,结合jest.resetModules重置模块缓存,就能实现隔离Mock。

describe("My test suite here", () => {
  beforeEach(() => {
    jest.clearAllMocks();
    jest.resetModules(); // 每次测试前清空模块缓存,避免Mock污染
  });

  test("Renders dialog1", async () => {
    // 动态导入被测试组件,使用真实的Dialog
    const MyComponent = (await import("../path/to/your/component")).default;
    render(<MyComponent />);
    // 你的断言逻辑
  });

  test("Renders dialog2", async () => {
    const MyComponent = (await import("../path/to/your/component")).default;
    render(<MyComponent />);
    // 你的断言逻辑
  });

  test("Renders dialog with mock", async () => {
    // 仅在此测试中Mock目标组件
    jest.doMock("@components/components-chat-dialog", () => ({
      ...jest.requireActual("@components/components-chat-dialog"),
      Dialog: jest.fn().mockImplementation(({ header, content }) => (
        <div>
          <div data-testid="dialog-header">{header}</div>
          <div data-testid="dialog-content">{content}</div>
        </div>
      )),
    }));

    // 动态导入被测试组件,此时会使用上面的Mock
    const MyComponent = (await import("../path/to/your/component")).default;
    render(<MyComponent />);
    
    // 你的断言逻辑
    expect(screen.getByTestId("dialog-header")).toBeInTheDocument();
  });

  test("Renders dialog3", async () => {
    const MyComponent = (await import("../path/to/your/component")).default;
    render(<MyComponent />);
    // 你的断言逻辑
  });
});

方案2:使用jest.spyOnMock单个导出

如果仅需要Mock模块中的单个导出(比如这里的Dialog),用jest.spyOn更简洁,测试后直接恢复原实现即可。

import MyComponent from "../path/to/your/component";

describe("My test suite here", () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  test("Renders dialog1", () => {
    render(<MyComponent />);
    // 你的断言逻辑
  });

  test("Renders dialog2", () => {
    render(<MyComponent />);
    // 你的断言逻辑
  });

  test("Renders dialog with mock", () => {
    // 创建Spy并替换Dialog的实现
    const mockDialog = jest.spyOn(require("@components/components-chat-dialog"), "Dialog")
      .mockImplementation(({ header, content }) => (
        <div>
          <div data-testid="dialog-header">{header}</div>
          <div data-testid="dialog-content">{content}</div>
        </div>
      ));

    render(<MyComponent />);
    // 你的断言逻辑
    expect(screen.getByTestId("dialog-header")).toBeInTheDocument();

    // 测试结束后恢复原Dialog组件
    mockDialog.mockRestore();
  });

  test("Renders dialog3", () => {
    render(<MyComponent />);
    // 你的断言逻辑
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 10:33:30