如何在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
相关产品推荐
相关产品推荐

