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
相关产品推荐
相关产品推荐

