使用react-testing-library测试Ant Design Modal打开功能失败如何解决?
问题根因
你的猜测是正确的,Ant Design 所有弹窗类组件(Modal、Drawer、Tooltip等)默认都会通过 React Portal 机制将内容挂载到 document.body 节点下,而 React Testing Library 中通过 render 方法返回的查询器默认查询范围仅为渲染生成的组件容器(默认是一个挂载在 body 下的独立 div),所以无法查询到 body 下挂载的 Modal 内容。
解决方法
方案1:使用全局查询的 screen 对象(最推荐,无需修改业务代码)
React Testing Library 提供的 screen 对象默认查询范围是整个 document,可以直接匹配到所有 Portal 挂载的内容,只需修改测试代码即可:
import { render, fireEvent, waitFor, screen } from '@testing-library/react'; test('modal opening', async () => { render(<ModalComponent />); fireEvent.click(screen.getByText('Open Modal')); await waitFor(() => expect(screen.getByText('Modal title')).toBeInTheDocument()); });
方案2:修改Modal挂载容器(需要修改业务代码)
如果需要将Modal限制在组件DOM树内,可以给Modal组件添加 getContainer={false} 属性,指定Modal挂载到其父节点下,不需要修改测试代码即可正常查询:
<Modal title="Modal title" centered visible={visible} onOk={() => setVisible(false)} onCancel={() => setVisible(false)} getContainer={false} // 新增该行配置 > <p>some contents...</p> <p>some contents...</p> <p>some contents...</p> </Modal>
方案3:手动指定查询根节点
如果你不想使用screen,也可以手动指定查询的根节点为document.body:
test('modal opening', async () => { const { getByText } = render(<ModalComponent />); fireEvent.click(getByText('Open Modal')); await waitFor(() => expect(getByText('Modal title', { container: document.body })).toBeInTheDocument()); });
注意事项
queryBy* 类查询方法未匹配到内容时会返回 null,适合判断元素不存在的场景;断言元素存在时推荐使用 getBy* 方法,未匹配到时会直接抛出错误,配合 waitFor 重试逻辑更稳定。
内容的提问来源于stack exchange,提问作者Shota
相关产品推荐
相关产品推荐

