如何限制testing-library的within仅查询第一代子元素?
如何限制查询仅统计顶级列表项?
我有如下两级嵌套列表结构:
<ul data-testid="parentList"> <li>First parent <ul> <li>Child of first parent</li> </ul> </li> <li>Second parent <ul> <li>Child of second parent</li> </ul> </li> </ul>
我想要断言父列表包含2个元素,尝试了以下代码:
const list = screen.getByTestId('parentList'); const listItems = within(list).getAllByRole('listitem'); expect(list).toHaveLength(2);
但由于within(list).getAllByRole('listitem')会统计子列表中的元素,导致断言失败:
Expected length: 2
Received length: 4
请问是否有办法限制within查询仅统计顶级列表项?
解决方案
1. 使用:scope选择器限定直接子元素
利用CSS的:scope选择器,结合Testing Library的查询方法,只获取父列表的直接子级listitem:
const list = screen.getByTestId('parentList'); // 限定查询范围为当前元素的直接子li const topLevelItems = within(list).getAllByRole('listitem', { selector: ':scope > li' }); expect(topLevelItems).toHaveLength(2);
:scope代表当前上下文(即parentList这个<ul>元素),> li表示仅匹配它的直接子节点中的<li>,这样就能排除子列表里的嵌套项。
2. 修正原代码的断言对象
你原代码存在一个错误:expect(list).toHaveLength(2)是断言<ul>元素的长度,这本身逻辑错误,应该断言查询到的列表项数组listItems的长度,结合上面的选择器就能得到正确结果。
3. 直接使用querySelectorAll
如果不需要Testing Library的查询特性,也可以直接用DOM API获取直接子元素:
const list = screen.getByTestId('parentList'); const topLevelItems = list.querySelectorAll(':scope > li'); expect(topLevelItems).toHaveLength(2);
内容的提问来源于stack exchange,提问作者Vidar S. Ramdal
相关产品推荐
相关产品推荐

