You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用React Testing Library监视AgGrid API调用

如何测试AgGrid的CSV导出按钮调用API的行为

问题场景

我有一个包含简易AgGrid的基础React组件,组件下方设置了调用AgGrid API(例如导出为CSV)的按钮:

const GridExample = () => {
    const api = useRef(null);
    const containerStyle = { width: '100%', height: '100%' };

    const [rowData, setRowData] = useState([
       { date: '12/12/2022  3:00PM' },
       { date: '10/31/2022  7:00PM' },
       { date: '10/30/2022  7:00AM' },
       { date: '10/1/2022  8:00AM' },
       { date: '8/31/2022  4:59PM' },
    ]);  

    const [columnDefs, setColumnDefs] = useState([
        { field: 'date' },
    ]);

    const gridReady = (params) => {
        api.current = params?.api;
        api.current.sizeColumnsToFit();
    }

    const csv = () => {
        api.current.exportDataAsCsv({
            filename: new Date()
        });
    }

    return (
        <div style={containerStyle}>
            <div style={containerStyle} className="ag-theme-alpine">
               <AgGridReact
                   rowData={rowData}
                   columnDefs={columnDefs}
                   onGridReady={gridReady}
               ></AgGridReact>
            </div>
        </div>

        <button onClick={csv}>CSV</button>
    );
};

在测试中,我可以断言网格已渲染,但难以mock上述api和exportDataAsCsv方法,无法验证点击按钮时该方法是否被调用。测试代码如下:

import React from 'react';
import { act, render, screen, fireEvent, RenderResult, waitFor } from '@testing-library/react';
import { GridExample } from './GridExample';

const waitForGridToBeInTheDOM=()=>{
    return waitFor(() => {
        expect(document.querySelector(".ag-root-wrapper")).toBeInTheDocument();
    });
}

describe('GridTest', () => {
    it('should expect date grid to render with Date column', async function () {
        let grid;
        await act( async () => {
            grid = render(<GridExample/>);
        });

        await waitForGridToBeInTheDOM();

        expect(screen.getByText('Date')).toBeInTheDocument();

        let btn = screen.getByText(/CSV/i);
        fireEvent.click(btn);

        // ..expect(api.export to CSV ).toHaveBeenCalled();
    });
});

解决方案

核心思路

通过Mock AgGridReact组件,手动控制onGridReady回调传入的API对象,追踪exportDataAsCsv方法的调用情况,无需依赖真实的AgGrid渲染逻辑。

修改后的测试代码

import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { GridExample } from './GridExample';

// Mock AgGridReact组件,自定义onGridReady传入的API
jest.mock('ag-grid-react', () => ({
  AgGridReact: (props) => {
    React.useEffect(() => {
      if (props.onGridReady) {
        // 创建带有mock方法的API对象
        const mockApi = {
          sizeColumnsToFit: jest.fn(),
          exportDataAsCsv: jest.fn()
        };
        props.onGridReady({ api: mockApi });
      }
    }, [props.onGridReady]);
    
    // 返回模拟的网格DOM结构,保证原有渲染断言生效
    return (
      <div className="ag-root-wrapper">
        <div>
          <span>Date</span>
        </div>
      </div>
    );
  }
}));

describe('GridTest', () => {
  it('should render Date column and call exportDataAsCsv when CSV button is clicked', async () => {
    render(<GridExample/>);
    
    // 验证网格渲染完成
    await waitFor(() => {
      expect(document.querySelector(".ag-root-wrapper")).toBeInTheDocument();
    });
    expect(screen.getByText('Date')).toBeInTheDocument();

    // 触发CSV按钮点击
    const csvBtn = screen.getByText(/CSV/i);
    fireEvent.click(csvBtn);

    // 获取mock的API对象并验证方法调用
    const { AgGridReact } = require('ag-grid-react');
    // 提取onGridReady回调中传入的mockApi
    const mockApiCall = AgGridReact.mock.calls[0][0].onGridReady.mock.calls[0][0].api;
    // 验证exportDataAsCsv被调用
    expect(mockApiCall.exportDataAsCsv).toHaveBeenCalled();
    // 可选:验证调用参数是否符合预期
    expect(mockApiCall.exportDataAsCsv).toHaveBeenCalledWith(expect.objectContaining({
      filename: expect.any(Date)
    }));
  });
});

关键说明

  1. Mock组件替代真实渲染:通过jest.mock替换AgGridReact,避免加载真实的AgGrid库,提升测试速度。
  2. 控制API对象:在mock组件中创建带有jest mock函数的api对象,传入onGridReady回调,让组件的api.current指向这个mock对象。
  3. 简化异步处理:移除原测试中多余的act包裹,React Testing Library的render和waitFor已自动处理异步更新。
  4. 保留原有断言逻辑:mock组件返回的DOM结构包含Date文本和ag-root-wrapper类,保证原有渲染断言能正常通过。

内容的提问来源于stack exchange,提问作者Oam Psy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 08:17:44