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

如何在Vitest中Mock react-modal的setAppElement函数?

解决React Modal测试中"找不到#root元素"的报错问题

问题原因

你遇到的问题是因为测试环境中不存在#root元素,但react-modal的无障碍要求必须调用setAppElement指定根节点,而你尝试mocksetAppElement的写法有误——react-modal的setAppElement是挂载在默认导出的Modal对象上的静态方法,不是独立导出的函数,所以你的mock没有覆盖到实际调用的方法。

解决方案

方案1:修正Vitest的Mock写法

调整mock逻辑,直接覆盖默认导出Modal对象上的setAppElement方法:

describe("CustomModal", () => {
  vi.mock("react-modal", async () => {
    const actual = await vi.importActual("react-modal");
    // 获取原始的默认导出Modal对象
    const originalModal = actual.default;
    return {
      ...actual,
      default: {
        ...originalModal,
        // 替换setAppElement为空函数或mock函数
        setAppElement: vi.fn()
      }
    };
  });

  it("Renders successfully", () => {
    render(<CustomModal />);
  });
});

方案2:在测试环境中创建#root元素

无需mock,直接在测试前后给document添加/移除#root元素,模拟真实环境:

describe("CustomModal", () => {
  let rootElement;

  beforeAll(() => {
    // 创建#root元素并添加到body
    rootElement = document.createElement('div');
    rootElement.id = 'root';
    document.body.appendChild(rootElement);
  });

  afterAll(() => {
    // 测试结束后清理元素
    document.body.removeChild(rootElement);
  });

  it("Renders successfully", () => {
    render(<CustomModal />);
  });
});

方案3:组件内动态适配测试环境

在设置setAppElement的代码中,判断是否处于测试环境,直接指定已存在的元素(比如body):

// 组件中的setAppElement代码
if (typeof document !== "undefined") {
  // 通过环境变量判断是否为测试环境(需根据你的测试框架配置)
  const isTest = import.meta.env.VITE_TEST === 'true';
  Modal.setAppElement(isTest ? 'body' : "#root");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:54:59