React测试入门:如何校验数组对象映射渲染后对应属性的文本内容
问题原因
ARIA的role属性只能使用W3C规范定义的合法枚举值,自定义的role值不被规范支持,所以测试工具无法通过自定义role定位元素。另外你使用的Collapse组件开启了unmountOnExit,默认折叠状态下列表项不会挂载到DOM中,不先展开的话也会找不到元素。
最优解决方案
推荐使用data-testid属性定位,这是测试专用属性,不会影响生产环境的功能和可访问性,是React Testing Library官方推荐的自定义元素定位方式。
步骤1:修改业务代码
把原来List上的自定义role替换为data-testid:
{data.map((el: ConnectedSelectionListProps) => ( <List data-testid="map-data-item" key={keyFromEl(el) + "sublist"}> {console.log("renders: ", el.name, el)} {renderListItem(keyFromEl(el), el.name, el)} </List> ))}
步骤2:修改测试代码
先触发展开操作,再定位元素断言:
test("test clicking ListItem", () => { const Items = [{ identifier: "0-0-0-2", name: "Camera 1" }]; render( <Provider store={store}> <SelectionList classes={{ button_basic: "" }} action={"cameras"} actionArgs={""} onUpdateClick={onClickCallback} onDeleteClick={onClickCallback} onDetailsClick={onClickCallback} /> </Provider> ); // 先点击头部展开折叠的列表 const listHeader = screen.getByText(/cameras/i); fireEvent.click(listHeader); // 定位所有列表项 const SelectionCardElement = screen.getAllByTestId("map-data-item"); expect(SelectionCardElement[0]).toHaveTextContent(Items[0].identifier); expect(SelectionCardElement[0]).toHaveTextContent(Items[0].name); });
替代方案(无需新增testid)
如果你不想新增自定义属性,也可以通过语义化查询实现:MUI的List组件默认role为list,你可以先定位到外层的SelectionList,再筛选内部的列表项:
// 先点击展开列表,操作同上 const outerList = screen.getByTestId("SelectionListt"); const innerLists = within(outerList).getAllByRole("list"); // 排除外层的List容器,剩下的就是map生成的子列表项 const mapItems = innerLists.slice(1); expect(mapItems[0]).toHaveTextContent(Items[0].identifier); expect(mapItems[0]).toHaveTextContent(Items[0].name);
内容的提问来源于stack exchange,提问作者walee
相关产品推荐
相关产品推荐

