React中使用React-testing-library测试AG-Grid分组单元格遇阻求助
问题:React-testing-library测试AG-Grid分组单元格失败
我在使用React-testing-library测试React项目中的AG-Grid分组单元格时遇到了问题。
Grid组件代码
const MyGrid = props => { const rowData = [ { model: 'samsung', name: 'My TV', room: 'living room', connectedDevices: [ { type: 'receiver', deviceName: 'My Receiver', } ] } ]; const detailCellRendererParams = { detailGridOptions: { columnDefs: [ {field: 'type'}, {field: 'deviceName'}, ], // suppressColumnVirtualisation: true, }, getDetailRowData: params => params.successCallback(params.node.data.connectedDevices), }; return ( <AgGridReact colDefs={[ {field: 'model'}, {field: 'name', cellRenderer: 'agGroupCellRenderer'}, {field: 'room'}, ]} rowData={rowData} masterDetail={true} detailCellRendererParams={detailCellRendererParams} suppressColumnVirtualisation={true} /> ); }
(注:原代码中colDefs的field值未加引号,属于语法错误,已修正)
测试代码
describe('Test MyGrid', () => { it('Should display the connected device in the detail grid', async () => { const groupCell = await screen.findByText('My TV'); user.dblClick(groupCell); // user.click(document.getElementsByClass('ag-icon-tree-closed')[0]); const connectedDevices = [ { type: 'receiver', deviceName: 'My Receiver', } ]; for (const d of connectedDevices) { expect(screen.getByText(d.name)).toBeInTheDocument(); } }); });
测试甚至无法通过await screen.findByText('My TV')这一步,通过screen.logTestingPlaygroundUrl()查看HTML时,仅能看到列头,找不到name列的实际网格单元格。我参考相关帖子尝试禁用详情网格的列虚拟化,但没有效果。请问有成功测试AG-Grid分组网格的方案吗?
解决方案
1. 修正组件语法错误
原组件colDefs中的field值未加引号,会导致列定义失效,AG-Grid无法正确绑定行数据,这是渲染失败的核心原因之一。
2. 禁用行虚拟化(关键)
AG-Grid默认开启行虚拟化,测试环境中可能不会渲染实际行数据。除了禁用列虚拟化,还需要在AgGridReact组件上添加行虚拟化禁用配置:
<AgGridReact // 其他配置不变 suppressColumnVirtualisation={true} suppressRowVirtualisation={true} // 新增该行 />
3. 等待网格完全渲染
AG-Grid是异步渲染的,需等待网格初始化完成后再进行查询。修改测试代码,通过waitFor等待行元素出现:
import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; describe('Test MyGrid', () => { it('Should display the connected device in the detail grid', async () => { const user = userEvent.setup(); render(<MyGrid />); // 等待主网格行渲染完成 await waitFor(() => { expect(screen.getByRole('row', { name: /My TV/ })).toBeInTheDocument(); }); // 触发分组展开 const groupCell = screen.getByText('My TV'); await user.dblClick(groupCell); // 等待详情网格渲染完成 await waitFor(() => { expect(screen.getByText('My Receiver')).toBeInTheDocument(); }); }); });
4. 避免直接操作原生DOM
测试中不要使用document.getElementsByClass这类原生DOM方法,统一用React-testing-library提供的查询方法(如getByRole、getByText),保证测试的稳定性。
5. 验证masterDetail配置
确认getDetailRowData方法正确返回详情数据,且详情网格的columnDefs字段名与数据字段完全匹配(原代码中该配置是正确的)。
内容的提问来源于stack exchange,提问作者Keanu Hasty
相关产品推荐
相关产品推荐

