You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 07:26:31