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

React Jest测试报错:TypeError: ... is not a function 问题咨询

错误原因分析

核心问题1:handleDiscard是组件内部私有变量,未对外暴露

你定义的handleDiscard是provider组件函数内部的局部变量,并没有作为模块导出成员对外提供。通过require("./implementation")拿到的actual对象,只有你显式导出的provider组件,根本不存在handleDiscard这个属性,直接调用actual.handleDiscard()自然会报错“不是函数”。

核心问题2:测试逻辑不符合React组件的运行规则

React函数组件内部的函数属于组件实例的私有逻辑,不能像调用普通模块导出函数那样直接调用。正确的测试思路应该是:

  • 先渲染provider组件
  • 如果handleDiscard是通过UI事件触发的(比如按钮点击),模拟对应的用户交互来触发它
  • 如果handleDiscard是通过Context暴露给子组件的,需要从Context中获取该函数后再调用

修正示例(假设通过Context暴露handleDiscard)

如果你的provider是通过Context提供这个方法,测试可以改成这样:

import { render, act } from '@testing-library/react';
import { provider, YourContext } from './implementation';

it('triggers discard', () => {
  let contextValue;
  // 渲染组件并捕获Context的值
  render(
    <YourContext.Consumer>
      {(value) => {
        contextValue = value;
        return null;
      }}
    </YourContext.Consumer>,
    { wrapper: provider }
  );

  act(() => {
    contextValue.handleDiscard(); // 从Context中拿到方法再调用
  });

  expect(invokeDiscard).toHaveBeenCalled();
});

修正示例(假设通过UI按钮触发)

如果handleDiscard是绑定到某个按钮的点击事件:

import { render, fireEvent, act } from '@testing-library/react';
import { provider } from './implementation';

it('triggers discard on button click', () => {
  const { getByText } = render(
    <provider>
      <button onClick={/* 此处绑定组件内部的handleDiscard */}>Discard</button>
    </provider>
  );
  
  act(() => {
    fireEvent.click(getByText('Discard'));
  });

  expect(invokeDiscard).toHaveBeenCalled();
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:11:26