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

创建Jest mock覆盖TableVirtuoso组件时报错如何解决?

Jest mock TableVirtuoso 触发构造函数报错修复

问题场景

测试用例中使用了react-virtuoso导出的TableVirtuoso组件,导入方式如下:

import { TableVirtuoso } from 'react-virtuoso';

为了在测试环境默认给组件注入initialItemCount属性(解决虚拟列表测试时不渲染子项的问题),尝试通过高阶组件包装原组件实现mock,最初编写的mock代码如下:

jest.mock('react-virtuoso', () => {
  const { TableVirtuoso } = jest.requireActual('react-virtuoso');

  const mockVirtuoso = (WrappedVirtuoso: ElementType) =>
    class extends mockComponent<{ totalCount: number }, unknown> {
      render() {
        return (
          <WrappedVirtuoso
            initialItemCount={this.props?.totalCount}
            {...this.props}
          />
        );
      }
    };
  return { TableVirtuoso: mockVirtuoso(TableVirtuoso) };
});

该实现参考了社区公开讨论的方案,但运行测试时抛出如下TypeError,无法正常执行用例:

TypeError: Class constructor  cannot be invoked without 'new'

      79 |   wrapperOptions?: WrapperOptions,
      80 | ) =>
    > 81 |   render(ui, {
         |   ^
      82 |     wrapper: props => <AllTheProviders {...props} {...wrapperOptions} />,
      83 |     ...options,
      84 |   });

报错原因

报错核心是两点:

  • 自定义的mockComponent基类没有正确实现ES类构造逻辑,在React渲染调用时没有走new实例化流程
  • Jest的mock模块提升机制会把jest.mock工厂函数提前到文件顶部执行,在类继承场景下容易拿到未初始化的真实组件引用,触发构造规则校验失败

修复代码

直接放弃类继承的HOC实现,改用函数组件包装原组件,同时透传原组件的所有静态属性,避免内置方法丢失:

jest.mock('react-virtuoso', () => {
  const React = require('react');
  const actualLib = jest.requireActual('react-virtuoso');
  const OriginalTableVirtuoso = actualLib.TableVirtuoso;

  const MockedTableVirtuoso = (props) => {
    return (
      <OriginalTableVirtuoso
        initialItemCount={props.totalCount}
        {...props}
      />
    );
  };

  // 透传原组件所有静态属性,比如scrollToIndex等内置方法
  Object.assign(MockedTableVirtuoso, OriginalTableVirtuoso);

  return {
    ...actualLib,
    TableVirtuoso: MockedTableVirtuoso,
  };
});

注意事项

  • 如果项目使用的是React 17+的新JSX转换,不需要在文件顶部导入React也可以正常写JSX
  • 如果只需要mock TableVirtuoso,其他导出项保持原有实现,一定要把真实库的其他导出项一起返回,避免其他用到库内方法的用例报错
  • 不要在mock工厂外部提前引用真实组件,否则会因为jest的mock提升机制拿到undefined引用

内容的提问来源于stack exchange,提问作者Renaud is Not Bill Gates

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 08:39:29