React Testing Library无法检测DataGrid行单元格问题排查
React Testing Library无法检测Material-UI DataGrid行单元格问题
当前问题
使用React Testing Library的查询方法,即便针对异步数据使用了正确的findBy类查询,仍无法检测到Material-UI DataGrid的行单元格及其中的数据。
预期行为
使用findBy类查询应使测试通过,且screen.debug()能显示渲染的行数据。
复现代码
import { render, screen } from '@testing-library/react'; import PerformanceDataGridModal from '../../features/PerformanceDataGridModal/PerformanceDataGridModal'; import ChartMockData from '../../utils/Mocks/ChartsMockData/ChartMockData'; import '@testing-library/jest-dom'; describe('Performance datagrid modal', () => { test.each(ChartMockData)('opens with correct information based on %s button click', async (item) => { const CloseDataGrid = jest.fn(); const ClosedDataGridModal = ( <PerformanceDataGridModal open={false} onclose={CloseDataGrid} rows={ChartMockData[item.id].rows} columns={ChartMockData[item.id].columns} /> ); const OpenedDataGridModal = ( <PerformanceDataGridModal open onclose={CloseDataGrid} rows={ChartMockData[item.id].rows} columns={ChartMockData[item.id].columns} /> ); render(ClosedDataGridModal); expect(screen.queryByRole('dialog')).toBeFalsy(); expect(screen.queryByRole('grid')).toBeFalsy(); expect(screen.queryByRole('cell', { name: 'Yes' })).toBeFalsy(); render(OpenedDataGridModal); expect(screen.getByRole('dialog')).toBeTruthy(); expect(screen.getByRole('grid')).toBeTruthy(); expect(await screen.findByRole('cell', { name: 'jane' })).toBeTruthy(); screen.debug(); }); });
注:已按照React Testing Library官方指南使用await screen.findByRole()处理异步渲染场景。
已尝试方案
- 使用
waitFor配合getBy类查询替代findBy类查询 - 按照Material-UI DataGrid文档设置
disableVirtualization参数 - 使用
jest.requireActual导入DataGrid并设置autoHeight - 显式等待组件渲染完成
- 对整个断言语句添加
await
解决方案
1. 彻底禁用DataGrid虚拟化并强制渲染所有行
DataGrid默认的虚拟化优化会导致测试时仅渲染可视区域内的行,必须在测试环境完全关闭该功能,同时设置autoHeight确保所有行被渲染:
// 测试代码中传递测试专用配置 const OpenedDataGridModal = ( <PerformanceDataGridModal open onclose={CloseDataGrid} rows={ChartMockData[item.id].rows} columns={ChartMockData[item.id].columns} disableVirtualization autoHeight /> );
也可以在PerformanceDataGridModal组件内部针对测试环境自动启用这些配置:
import { DataGrid } from '@mui/x-data-grid'; function PerformanceDataGridModal({ rows, columns, ...props }) { const isTest = process.env.NODE_ENV === 'test'; return ( <DataGrid rows={rows} columns={columns} disableVirtualization={isTest} autoHeight={isTest} {...props} /> ); }
2. 调整查询逻辑,匹配单元格实际文本
Material-UI DataGrid的单元格name属性不一定直接对应显示文本,改用findByText()直接匹配内容更可靠:
// 替换原断言 expect(await screen.findByText('jane')).toBeInTheDocument();
如果单元格文本嵌套在子元素中,可通过within()缩小查询范围:
const grid = screen.getByRole('grid'); expect(await within(grid).findByText('jane')).toBeInTheDocument();
3. 使用rerender替代重复render避免状态残留
当前测试中两次调用render可能导致环境状态混乱,改用React Testing Library提供的rerender方法复用组件实例:
test.each(ChartMockData)('opens with correct information based on %s button click', async (item) => { const CloseDataGrid = jest.fn(); const { rerender } = render( <PerformanceDataGridModal open={false} onclose={CloseDataGrid} rows={ChartMockData[item.id].rows} columns={ChartMockData[item.id].columns} disableVirtualization autoHeight /> ); expect(screen.queryByRole('dialog')).toBeFalsy(); expect(screen.queryByRole('grid')).toBeFalsy(); // 重新渲染为打开状态 rerender( <PerformanceDataGridModal open onclose={CloseDataGrid} rows={ChartMockData[item.id].rows} columns={ChartMockData[item.id].columns} disableVirtualization autoHeight /> ); expect(screen.getByRole('dialog')).toBeInTheDocument(); expect(screen.getByRole('grid')).toBeInTheDocument(); expect(await screen.findByText('jane')).toBeInTheDocument(); screen.debug(); });
4. 验证Mock数据正确性
检查ChartMockData[item.id].rows是否确实包含带有jane文本的行,可在测试中临时打印数据确认:
console.log('当前测试行数据:', ChartMockData[item.id].rows);
内容的提问来源于stack exchange,提问作者Samora Mabuya
相关产品推荐
相关产品推荐

