React+MUI Tooltip高阶组件(HOC)的RTL测试问题
搞定你的InfoHOC测试问题!
我来帮你拆解下当前遇到的问题,主要是HOC调用方式不对,加上MUI Tooltip的特性导致测试逻辑有误区,一步步来解决:
首先,你的HOC调用错了!
高阶组件(HOC)是用来包裹**组件(函数/类)**的,不是直接传已渲染的JSX元素。你现在写的:
const Component = InfoHoc(<div>jest div</div>)({ message: 'jest infoHoc message' });
相当于把一个现成的React元素塞给了HOC,虽然能渲染,但不符合HOC的设计逻辑,也可能给测试带来隐藏问题。正确的打开方式应该是:
// 先定义一个基础组件 const TestDiv = () => <div>jest div</div>; // 用HOC包裹它,得到新的组件 const WrappedTestDiv = InfoHOC(TestDiv); // 渲染这个新组件时,再传入message props render(<WrappedTestDiv message="jest infoHoc message" />);
然后,测试逻辑的几个坑要避开
1. MUI Tooltip有默认延迟,不能立刻断言
MUI的Tooltip默认会等100ms才显示,你触发mouseover后马上就查元素,肯定找不到!得用React Testing Library的waitFor来等DOM更新完成。
2. 用错了查询方法
getByDisplayValue是给表单输入元素用的(比如input的value),Tooltip里的是普通文本,应该用getByText或者getByRole('tooltip')来查。
3. Portal元素要用全局查询
Tooltip是通过Portal渲染到document.body里的,用RTL的screen对象来查询更靠谱,它是基于整个文档的,比render返回的局部查询更适合找Portal内容。
修正后的完整测试代码
import { render, fireEvent, waitFor, screen } from '@testing-library/react'; import InfoHOC from './InfoHOC'; it('should display info message on mouseover', async () => { // 正确调用HOC const TestDiv = () => <div>jest div</div>; const WrappedComponent = InfoHOC(TestDiv); // 渲染包裹后的组件 render(<WrappedComponent message="jest infoHoc message" />); // 获取InfoIcon(这里用title属性定位,你也可以给Icon加aria-label让测试更健壮) const infoIcon = screen.getByTitle('jest infoHoc message'); // 触发鼠标悬停 fireEvent.mouseOver(infoIcon); // 等待Tooltip渲染完成,然后断言 await waitFor(() => { // 两种查询方式选一个就行 expect(screen.getByText('jest infoHoc message')).toBeInTheDocument(); // 或者用role查询:expect(screen.getByRole('tooltip')).toHaveTextContent('jest infoHoc message'); }); });
额外优化小技巧
如果你嫌100ms的延迟拖慢测试,可以给Tooltip加个enterDelay={0}的props。要么修改你的HOC让它支持传递Tooltip的额外属性:
const InfoHOC = (HocComponent) => ({ message, tooltipProps = {} }) => ( <> <Tooltip title={message} {...tooltipProps}> <InfoIcon /> </Tooltip> <HocComponent /> {/* 这里改成组件标签形式,方便后续传props给包裹的组件 */} </> );
然后测试时传进去:
render(<WrappedComponent message="jest infoHoc message" tooltipProps={{ enterDelay: 0 }} />);
这样测试时就不用等延迟了,不过我还是建议保留waitFor,更贴近真实用户的交互场景~
内容的提问来源于stack exchange,提问作者Tralgar
相关产品推荐
相关产品推荐

