如何使用React Testing Library测试含<use>标签的<svg>组件?
React Testing Library 测试SVG use标签属性的正确姿势(不用container/全局查询)
问题场景
我有如下组件结构:
<span className={containerClassName} data-testid="iconId"> <svg role="img" className={svgClassName}> <use href="#iconhref" /> <title>iconTitle</title> </svg> iconText </span>
想用React Testing Library写单元测试,要求:
- 不使用render返回的
container - 避免用
document.querySelector('use')这种全局查询方式
当前测试代码里最后一行断言存在错误(外层span并不具备href属性):
// 验证图标可见及标题存在 expect(screen.getByRole('img')).toBeVisible(); expect(screen.getByTitle('iconTitle')).toBeInTheDocument(); // 错误的断言:外层span没有href属性 expect(screen.getByTestId('iconId')).toHaveAttribute('href', '#iconhref');
解决方案
方案1:不修改组件代码,限定查询范围
利用RTL的within方法,将查询范围限定在已定位的SVG元素内部,既避免全局查询,也符合测试隔离性要求:
// 基础验证:图标可见、标题存在 expect(screen.getByRole('img')).toBeVisible(); expect(screen.getByTitle('iconTitle')).toBeInTheDocument(); // 验证use标签的href属性 const svgElement = screen.getByRole('img'); // 仅在目标svg内部查询use标签,比全局document.querySelector更精准 const useElement = within(svgElement).querySelector('use'); expect(useElement).toHaveAttribute('href', '#iconhref');
方案2:修改组件代码,添加testid(更符合RTL规范)
如果可以调整组件结构,给<use>标签新增data-testid,直接通过testid查询元素,代码更简洁直观:
<span className={containerClassName} data-testid="iconId"> <svg role="img" className={svgClassName}> <use href="#iconhref" data-testid="icon-use-element" /> <title>iconTitle</title> </svg> iconText </span>
对应的测试代码:
// 基础验证 expect(screen.getByRole('img')).toBeVisible(); expect(screen.getByTitle('iconTitle')).toBeInTheDocument(); // 直接查询use标签并断言属性 expect(screen.getByTestId('icon-use-element')).toHaveAttribute('href', '#iconhref');
内容的提问来源于stack exchange,提问作者sparkkx_stealer
相关产品推荐
相关产品推荐

