React Testing Library中如何获取仅含图标的NavLink?
问题
在React Testing Library单元测试中,无法通过getByRole('link', { name: 'help' })获取仅包含图标的NavLink,报错提示找不到对应名称的link角色元素。原因是该NavLink没有文本内容,仅包含一个帮助图标,导致无障碍名称为空。
相关NavBar组件代码:
const NavBar = () => { return ( <> <div className="navbar"> <ul> <li> <NavLink to="home" className={({isActive}) => (isActive ? 'active' : 'inactive')}>Home</NavLink> </li> <li> <NavLink to="about" className={({isActive}) => (isActive ? 'active' : 'inactive')}>About</NavLink> </li> <li> <NavLink to="help" name="help" className={({isActive}) => (isActive ? 'active' : 'inactive')}><FaQuestionCircle size='1.5rem' className="helpicon"/></NavLink> </li> </ul> </div> </> ); }; export default NavBar;
失败的单元测试代码:
describe(Navbar, () => { const mockedNavigation = jest.fn(); it('should navigate to help page', () => { const { getByRole } = render(<Navbar />, { wrapper: Router }); fireEvent.click(getByRole('link', { name: 'help' })); expect(mockedNavigation).toHaveBeenCalledWith( "help", { preventScrollReset: undefined, relative: undefined, replace: false, state: undefined, unstable_viewTransition: undefined }); }); });
请问如何选择这种仅含图标、无文本的NavLink?是否有比添加额外className更简洁易读的方法?
解决方案
1. 添加aria-label属性(推荐)
为NavLink添加aria-label属性,直接指定无障碍名称,既符合无障碍设计规范,又能让getByRole直接定位:
修改组件代码:
<NavLink to="help" aria-label="help" className={({isActive}) => (isActive ? 'active' : 'inactive')} > <FaQuestionCircle size='1.5rem' className="helpicon"/> </NavLink>
测试代码无需修改,getByRole('link', { name: 'help' })即可正常找到元素。
2. 给图标添加alt文本
如果图标组件支持alt属性(如Font Awesome的组件),可以为图标设置alt值,该值会被作为父链接的无障碍名称:
<NavLink to="help" className={({isActive}) => (isActive ? 'active' : 'inactive')} > <FaQuestionCircle size='1.5rem' className="helpicon" alt="help"/> </NavLink>
同样,原测试代码的getByRole查询可以正常工作。
3. 通过href筛选元素
如果不想修改组件代码,可借助链接的href属性筛选,但这种方式优先级低于无障碍属性方案:
fireEvent.click(getByRole('link', { href: '/help' }));
注意:href值需与路由实际生成的路径一致,比如相对路由可能需要调整为完整路径。
4. 使用屏幕阅读器专用文本
添加视觉隐藏的文本,既不影响页面显示,又能提供明确的名称,同时提升无障碍性:
<NavLink to="help" className={({isActive}) => (isActive ? 'active' : 'inactive')} > <FaQuestionCircle size='1.5rem' className="helpicon"/> <span className="sr-only">Help</span> </NavLink>
需配合对应的CSS类:
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0; }
此时测试代码可通过getByRole('link', { name: 'Help' })定位元素。
内容的提问来源于stack exchange,提问作者Scottish Smile
相关产品推荐
相关产品推荐

