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

如何用Jest正确模拟React复合组件?

问题描述

我有一个如下所示的React复合组件:

export const Layout = Object.assign(Main, {
    Top, Content, Center, Left, Right,
})

该组件通过Object.assign将Main与其他组件绑定,支持点符号调用。我尝试在jest.setup.js文件中按如下方式模拟它:

jest.mock(
    '~/layouts/Layout', () => ({
        __esModule: true,
        default: (props) => {
            return <mock-layout>{props.children}</mock-layout>
        },
    }),
)

运行jest --ci时返回错误:Cannot read properties of undefined (reading 'Top')。我尝试了另一种写法:

const component = (props) => <layout-mock>{props.children}</layout-mock>;
component.Top = (props) => <layout-mock-top>{props.children}</layout-mock-top>;

jest.mock(
    '~/layouts/Layout', () => ({
        __esModule: true,
        default: component,
    }),
)

但仍出现相同错误,请问该如何正确模拟这个复合组件?

解决方法

问题出在导出方式不匹配:原组件是命名导出(export const Layout),但你之前的mock代码都在模拟默认导出(default),导致代码中import { Layout } from '~/layouts/Layout'拿到的是undefined,自然访问Layout.Top会报错。

正确的mock写法需要对齐原组件的命名导出:

// 创建模拟的主Layout组件
const MockLayout = (props) => <mock-layout>{props.children}</mock-layout>;

// 给主组件挂载所有需要的子组件属性,和原组件保持一致
MockLayout.Top = (props) => <mock-layout-top>{props.children}</mock-layout-top>;
MockLayout.Content = (props) => <mock-layout-content>{props.children}</mock-layout-content>;
MockLayout.Center = (props) => <mock-layout-center>{props.children}</mock-layout-center>;
MockLayout.Left = (props) => <mock-layout-left>{props.children}</mock-layout-left>;
MockLayout.Right = (props) => <mock-layout-right>{props.children}</mock-layout-right>;

jest.mock('~/layouts/Layout', () => ({
  __esModule: true,
  // 导出命名的Layout,和原组件的导出名称完全一致
  Layout: MockLayout,
}));

核心要点:

  • 原组件用export const Layout导出,mock时必须在返回对象中提供同名的Layout属性
  • 确保所有子组件(Top、Content等)都挂载到模拟的主组件上,保持和原组件一致的结构

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 22:18:26