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

如何使用Jest对React组件中history.push的onClick函数做单元测试?

React组件onClick事件单元测试问题

问题背景

需要对以下React组件中的Add按钮onClick函数做Jest单元测试,但现有测试代码报错。

组件代码

const baseURL = "/Security/Users/";

return (
    <div>
      <div className="flex-between">
        <button
          className="bt-save"
          onClick={() => history.push(baseURL + "Add")}
        >
          Add
        </button>
       </div>
    </div>
);

现有测试代码

it('Should run the callback function when clicked', async () => {
    const onClick = jest.fn(baseURL + "Add")

    render(<button push={onClick}> Add </button>)

    const addButton = screen.getByText('Add')
    await userEvent.click(addButton)
    expect(onClick).toHaveBeenCalled()
})

错误原因分析

  1. 测试逻辑脱离组件实际逻辑:原组件按钮的onClick是调用history.push,但测试代码手动创建了一个带push属性的假按钮,没有渲染真实组件,完全偏离了测试目标。
  2. jest.fn用法错误:jest.fn()接受函数作为默认实现参数,你传入字符串的写法完全不符合API规范。
  3. 未处理组件依赖的history对象:组件依赖React Router的history对象,测试环境中未模拟该依赖,导致逻辑无法正常执行。

正确测试方案

方案一:使用MemoryRouter(贴近真实路由场景)

通过React Router提供的MemoryRouter模拟路由环境,直接验证跳转后的路径:

import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MemoryRouter } from 'react-router-dom';
import YourComponent from './YourComponent'; // 替换为你的组件实际路径

it('点击Add按钮后跳转到正确的添加页面', async () => {
  render(
    <MemoryRouter>
      <YourComponent />
    </MemoryRouter>
  );

  const addButton = screen.getByText('Add');
  await userEvent.click(addButton);

  // 验证当前路由路径是否符合预期
  expect(window.location.pathname).toBe('/Security/Users/Add');
});

方案二:Mock useHistory钩子

如果组件通过useHistory钩子获取history对象,可以直接mock该钩子来验证方法调用:

import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { useHistory } from 'react-router-dom';
import YourComponent from './YourComponent';

// Mock react-router-dom的useHistory钩子
jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useHistory: jest.fn(),
}));

it('点击Add按钮时调用history.push并传入正确路径', async () => {
  const mockPush = jest.fn();
  // 让useHistory返回包含mock方法的history对象
  useHistory.mockReturnValue({ push: mockPush });

  render(<YourComponent />);

  const addButton = screen.getByText('Add');
  await userEvent.click(addButton);

  // 验证push方法被正确调用,参数符合预期
  expect(mockPush).toHaveBeenCalledWith('/Security/Users/Add');
});

内容的提问来源于stack exchange,提问作者Dasun sucharith

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 04:45:45