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

Jest mock React类组件方法报type is invalid错误如何解决

问题根源

你当前的mock写法存在两个核心问题,直接触发了报错:

  1. jest.mock工厂函数返回的普通对象丢失了原模块的default导出:原组件通过export default导出类,你直接展开jest.requireActual返回的模块对象后,导入的MyDataTable实际上是包含default属性的普通模块对象,不是组件类本身。React渲染时接收到object类型的组件,就会抛出「type is invalid」的类型错误。
  2. 你尝试在模块层面添加的loadIframe属性不会生效:loadIframe是类的实例原型方法,不是模块导出的静态方法,就算修正了导出问题,组件实例调用的还是原型链上的原有方法,无法达到拦截效果。
正确实现方案

不要用jest.mock整体mock组件模块,直接在类原型上监听、mock实例方法即可,既不会破坏组件正常导出,也能精准拦截方法调用,阻止真实iframe加载。
修改后的测试代码:

import "@testing-library/jest-dom";
import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import axios from "axios";
import MyDataTable from "../../components/DataTable/MyDataTable";

jest.mock("axios");

beforeEach(() => {
  // 监听类原型上的loadIframe方法,替换为mock实现
  jest.spyOn(MyDataTable.prototype, "loadIframe").mockImplementation((id) => {
    // 此处可自定义mock逻辑,留空即可完全阻止原有setState执行,避免iframe加载
    // 若需要验证iframe渲染逻辑,可手动设置符合预期的state
  });
});

afterEach(() => {
  // 恢复原有方法,避免mock污染其他测试用例
  jest.restoreAllMocks();
});

describe("My tests", () => {
  it("should load iframe on row click", async () => {
    const data = [
        ["row 1, col 1", "row 1, col 2"],
        ["row 2, col 1", "row 2, col 2"]
    ];
    axios.post.mockResolvedValue({ data });

    render(<MyDataTable id="test_id"/>);

    await waitFor(() => expect(axios.post).toHaveBeenCalled());
    
    userEvent.click(screen.getAllByRole("gridcell")[0]);
    // 可直接断言mock方法被调用
    expect(MyDataTable.prototype.loadIframe).toHaveBeenCalled();
    // 若mock中保留了iframe渲染逻辑,再添加DOM存在性断言即可
  });
});

可选的整模块mock写法(不推荐)

如果必须使用jest.mock整体mock模块,需要手动继承原类重写实例方法,同时保留default导出,维护成本更高:

jest.mock("../../components/DataTable/MyDataTable", () => {
  const actualModule = jest.requireActual("../../components/DataTable/MyDataTable");
  const OriginalComponent = actualModule.default;
  return {
    ...actualModule,
    default: class MockedDataTable extends OriginalComponent {
      loadIframe = jest.fn((id) => {
        // 自定义mock逻辑
      })
    }
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 09:39:58