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

