ag-grid React Enzyme测试onGridReady报dispatchEvent null错误咨询
问题1:正确测试onGridReady函数,避免报错并验证调用次数
你遇到的报错是因为模拟触发onGridReady时没有传入必填的api参数,且测试逻辑存在两处错误:
- 你在测试文件顶层定义的
onGridReadymock和组件内部的onGridReady没有关联,无法统计内部函数的调用情况 simulate方法适用于DOM事件,ag-grid的事件是组件props,直接调用对应prop即可
修改方案:
- 提前构造mock的GridApi对象,包含你用到的
sizeColumnsToFit、setHeaderHeightmock方法 - 直接获取
AgGridReact组件的onGridReadyprop,传入构造好的参数触发执行 - 验证
api相关方法被调用即可
测试代码示例:
it('测试onGridReady触发逻辑正确', () => { // 构造mock api const mockGridApi = { sizeColumnsToFit: jest.fn(), setHeaderHeight: jest.fn() } const { wrapper } = setUpMyTableComponent() // 注意如果用shallow渲染需要先dive到MyTable组件内部,再找AgGridReact const agGridInstance = wrapper.find(AgGridReact).first() // 直接调用prop传入参数 agGridInstance.props().onGridReady({ api: mockGridApi }) // 验证api方法被正确调用 expect(mockGridApi.sizeColumnsToFit).toHaveBeenCalledTimes(1) expect(mockGridApi.setHeaderHeight).toHaveBeenCalledWith(10) })
问题2:测试onGridSizeChanged函数
onGridSizeChanged依赖gridApi状态,分两种场景测试即可:
- gridApi未初始化时调用,不会抛出错误,也不会执行
sizeColumnsToFit - 先触发onGridReady给gridApi赋值后调用,验证
sizeColumnsToFit被触发
测试代码示例:
it('测试onGridSizeChanged逻辑正确', () => { const mockGridApi = { sizeColumnsToFit: jest.fn(), setHeaderHeight: jest.fn() } const { wrapper } = setUpMyTableComponent() const agGridInstance = wrapper.find(AgGridReact).first() // 场景1:gridApi未初始化 agGridInstance.props().onGridSizeChanged() expect(mockGridApi.sizeColumnsToFit).not.toHaveBeenCalled() // 场景2:gridApi已初始化 agGridInstance.props().onGridReady({ api: mockGridApi }) agGridInstance.props().onGridSizeChanged() expect(mockGridApi.sizeColumnsToFit).toHaveBeenCalledTimes(1) // 顺便验证onModelUpdated绑定的是同一个函数 expect(agGridInstance.props().onModelUpdated).toBe(agGridInstance.props().onGridSizeChanged) })
问题3:覆盖setTableData对应的行
该行在依赖myTableData、selectedCountryName的useEffect中,只要让useEffect的触发条件满足即可:
myTableData有有效值selectedCountryName不为空字符串
你用了redux的Provider,在初始化mock store的时候给对应的状态赋值即可:
// 修改setup函数,支持传入自定义store状态 function setUpMyTableComponent(customStoreState = {}) { const mockStore = configureStore([])({ myTableData: [], // 赋值非空的测试数据 selectedCountryName: '中国', // 赋值非空字符串 businessDate: '2024-01-01', ...customStoreState }) const wrapper = mount( <Provider store={mockStore}> <MyTable /> </Provider> ) return { wrapper, mockStore } } it('触发useEffect覆盖setTableData行', () => { const { wrapper } = setUpMyTableComponent({ myTableData: [{ id: 1, value: '测试数据' }], selectedCountryName: '美国' }) // 验证tableData和传入的myTableData一致即可 const agGridInstance = wrapper.find(AgGridReact).first() expect(agGridInstance.props().rowData).toEqual([{ id: 1, value: '测试数据' }]) })
其他注意事项
- 你的组件名是
myTable,首字母要大写改成MyTable,否则React会识别为原生标签 - 原测试代码中
dataGrid.simulate('onGridReady')的dataGrid变量不存在,属于笔误 - 测试React组件的hooks逻辑时,用mount渲染比shallow更稳定,避免多嵌套组件找不到内部实例的问题
内容的提问来源于stack exchange,提问作者beedeegeezz
相关产品推荐
相关产品推荐

