如何测试React.createPortal渲染的组件?Jest+RTL测试报错
解决React Portal组件在Jest+React Testing Library测试中的"Target container is not a DOM element"错误
问题出在你的Popup组件使用React.createPortal时,依赖的目标DOM容器在Jest的jsdom测试环境中不存在。生产环境里你可能在index.html中预先定义了这个容器(比如<div id="modal-root"></div>),但测试环境默认不会包含它,所以渲染时找不到目标元素报错。
以下是两种可行的解决方法:
方法一:测试前后手动创建/移除目标容器
在测试用例执行前后,手动向jsdom的document中添加和移除Portal所需的DOM容器:
import { render, screen } from '@testing-library/react'; import Popup from './Popup'; describe('PopUp', () => { let modalRoot; beforeEach(() => { // 创建目标容器并添加到body,id需和Popup组件中使用的一致 modalRoot = document.createElement('div'); modalRoot.setAttribute('id', 'modal-root'); document.body.appendChild(modalRoot); }); afterEach(() => { // 测试结束后移除容器,避免影响其他测试 document.body.removeChild(modalRoot); }); it("Render PopUp Properly", () => { const props = { setIsOpen: jest.fn(), children: <div>Test</div>, }; render(<Popup isOpen={true} {...props} />); expect(screen.getByTestId("popup-component")).toBeInTheDocument(); }); });
方法二:给Popup组件添加可配置的容器属性
修改Popup组件,允许传入自定义的容器元素,这样测试时可以直接传入一个临时创建的DOM节点:
第一步:修改Popup组件
import { createPortal } from 'react'; const Popup = ({ isOpen, setIsOpen, children, container }) => { // 默认使用页面中的modal-root,没有则用传入的容器 const targetContainer = container || document.getElementById('modal-root'); if (!isOpen) return null; return createPortal( <motion.div data-testid="popup-component"> {/* 组件原有内容 */} {children} </motion.div>, targetContainer ); }; export default Popup;
第二步:修改测试代码
import { render, screen } from '@testing-library/react'; import Popup from './Popup'; it("Render PopUp Properly", () => { const testContainer = document.createElement('div'); document.body.appendChild(testContainer); const props = { setIsOpen: jest.fn(), children: <div>Test</div>, container: testContainer // 传入自定义容器 }; render(<Popup isOpen={true} {...props} />); expect(screen.getByTestId("popup-component")).toBeInTheDocument(); // 清理临时容器 document.body.removeChild(testContainer); });
这两种方法都能解决测试环境中找不到Portal目标容器的问题,你可以根据项目需求选择合适的方案。
内容的提问来源于stack exchange,提问作者Birat Poudel
相关产品推荐
相关产品推荐

