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

React onClick函数测试失败求助:Mock函数后测试仍不通过

React组件测试中Mock函数未触发的修复方案

我有一个React计算器组件和对应的测试代码,已经尝试Mock相关函数,但测试始终失败。使用版本:@testing-library/react ^14.2.1、react ^18.2.0,求修复方法。

组件代码:

import { useCalculator } from "./hooks/useCalculator";

export const CalculatorApp = () => {
  const { displayNumber, operation, display, answer, reset } = useCalculator();

  return (
    <>
      <div className="container">
        <p>Calculator - React</p>
        <div className="calculator">
          <div aria-label="display">{displayNumber}</div>

          <div className="calculator__keys">
            <button
              onClick={() => operation("addition")}
              aria-label="addition"
            >
              +
            </button>
            ...
            <button aria-label="seven" onClick={() => display(7)}>7</button>
            ...
          </div>
        </div>
      </div>
    </>
  );
}

测试代码:

import { fireEvent, render, screen } from "@testing-library/react";
import { CalculatorApp } from "../src/CalculatorApp.jsx";

describe("Component test <CalculatorApp/>", () => {

  const mockOperation = jest.fn();

  beforeEach(() => jest.clearAllMocks());

  test("should call a matematical operation", () => {
    render(<CalculatorApp />);

    const selectedOperation = screen.getByLabelText("addition");
    fireEvent.click(selectedOperation);

    expect(mockOperation).toHaveBeenCalled();
    expect(mockOperation).toHaveBeenCalledWith("addition");
  });
});

问题根源

你定义了mockOperation但没有让组件使用这个Mock函数——组件依然调用的是useCalculator原hook里的operation方法,所以测试时mockOperation永远不会被触发。

修复方案

用jest.mockMock整个useCalculator模块,让组件使用我们定义的Mock函数。修改后的测试代码如下:

import { fireEvent, render, screen } from "@testing-library/react";
import { CalculatorApp } from "../src/CalculatorApp.jsx";
// 导入并Mock整个useCalculator模块
import { useCalculator } from "../src/hooks/useCalculator";
jest.mock("../src/hooks/useCalculator");

describe("Component test <CalculatorApp/>", () => {
  const mockOperation = jest.fn();

  beforeEach(() => {
    jest.clearAllMocks();
    // 让Mock的useCalculator返回包含自定义Mock函数的对象
    useCalculator.mockReturnValue({
      displayNumber: "",
      operation: mockOperation,
      display: jest.fn(),
      answer: jest.fn(),
      reset: jest.fn()
    });
  });

  test("should call a mathematical operation", () => {
    render(<CalculatorApp />);

    const selectedOperation = screen.getByLabelText("addition");
    fireEvent.click(selectedOperation);

    expect(mockOperation).toHaveBeenCalled();
    expect(mockOperation).toHaveBeenCalledWith("addition");
  });
});

关键说明

  • jest.mock("../src/hooks/useCalculator"):告诉Jest替换整个useCalculator模块为Mock版本,组件会优先使用这个Mock而非原hook。
  • useCalculator.mockReturnValue(...):在每个测试前重置Mock的返回值,确保组件解构出的operation就是我们定义的mockOperation。
  • 必须在beforeEach中重置返回值,避免不同测试用例之间的Mock状态互相污染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 12:40:07