React Testing Library测试Salt Design System Tooltip找不到元素问题排查
解决Salt Design System Tooltip组件RTL测试无法找到元素的问题
问题描述
我在代码中使用Salt Design System的Tooltip组件,尝试通过React Testing Library编写单元测试,当触发按钮的mouseover事件后,无法在文档中找到Tooltip元素。经排查发现Tooltip是通过Portal渲染在根元素外部的,请问哪里操作有误?
组件代码(App.tsx)
import { Button, Tooltip } from "@salt-ds/core"; function App() { return ( <Tooltip content="hakuna matata"> <Button>Click me</Button> </Tooltip> ); } export default App;
测试代码(App.spec.tsx)
import { act, fireEvent, render, screen, waitFor, } from "@testing-library/react"; import App from "./App"; import userEvent from "@testing-library/user-event"; describe("App", () => { it("should open tooltip", async () => { render(<App />); const btn = screen.getByText("Click me"); expect(btn).toBeInTheDocument(); fireEvent.mouseOver(btn); expect(await screen.findByText("hakuna matata")).toBeInTheDocument(); }); });
问题原因与解决方法
1. Portal元素不在默认查询范围内
React Testing Library的screen对象默认只查询组件渲染时挂载的根节点(通常是div#root),而Salt的Tooltip通过Portal将内容渲染到document.body或其他外部节点,因此默认查询无法命中。
2. 优化测试逻辑
- 使用
userEvent模拟真实hover:fireEvent.mouseOver仅触发单个事件,而userEvent.hover会模拟完整的用户鼠标悬停行为,适配组件可能存在的延迟显示逻辑。 - 扩大查询范围到
document.body:通过within(document.body)来定位Portal渲染的Tooltip内容。
修改后的测试代码:
import { render, screen, within, waitFor } from "@testing-library/react"; import App from "./App"; import userEvent from "@testing-library/user-event"; describe("App", () => { it("should display tooltip on button hover", async () => { render(<App />); const button = screen.getByText("Click me"); // 模拟真实用户悬停操作 await userEvent.hover(button); // 在document.body中查询Tooltip内容,处理渲染延迟 await waitFor(() => { const tooltipContent = within(document.body).getByText("hakuna matata"); expect(tooltipContent).toBeInTheDocument(); }); }); });
额外注意事项
若Tooltip配置了显示延迟(Salt组件默认可能存在短延迟),必须用waitFor包裹断言,确保等待元素完成异步渲染后再进行校验,避免测试失败。
内容的提问来源于stack exchange,提问作者Pratik Wadekar
相关产品推荐
相关产品推荐

