NextJS项目中用Jest测试Grommet UI组件遇pageHeader未定义错误
解决Grommet UI + NextJS项目中Jest测试
TypeError: Cannot read properties of undefined (reading 'pageHeader')问题 问题场景
在使用Grommet UI的NextJS项目中,测试包含PageHeader的RegionDetail组件时,直接调用render(<RegionDetail title="test" />)会抛出TypeError: Cannot read properties of undefined (reading 'pageHeader')错误,但将组件包裹在<Grommet plain>中后测试即可通过。
相关代码示例:
- Layout组件(已用Grommet包裹):
type LayoutProps = { children: React.ReactNode, }; export default function Layout({ children }: LayoutProps) { return ( <Grommet plain> <Page kind="narrow"> <PageContent> <main>{children}</main> </PageContent> </Page> </Grommet> ) }
- 待测试的RegionDetail组件:
const RegionDetail: React.FC<{ title: string }> = ({title}) => { return ( <section> <PageHeader title={ title }></PageHeader> </section> ); };
原因分析
Grommet的组件(如PageHeader)依赖**Grommet上下文(Context)**提供的主题(Theme)配置,pageHeader是主题内置的配置项之一。单独测试组件时,没有被<Grommet>组件包裹,导致上下文未初始化,PageHeader无法读取主题中的pageHeader属性,从而触发报错。
解决方案
方案1:单个测试用例中手动包裹Grommet
直接在测试代码中用<Grommet>包裹待测试组件,确保上下文正常初始化:
describe('RegionDetails', () => { test('Region Details', () => { render(<Grommet plain><RegionDetail title="test" /></Grommet>); }); });
方案2:全局配置测试包裹组件(避免重复代码)
如果项目中大量组件都依赖Grommet上下文,可以通过Jest的全局配置统一处理:
- 创建测试全局配置文件(如
jest.setup.ts):
import { render } from '@testing-library/react'; import { Grommet } from 'grommet'; // 重写render方法,默认给组件包裹Grommet上下文 const customRender = (ui: React.ReactElement, options?: any) => render(<Grommet plain>{ui}</Grommet>, options); // 导出原testing-library的所有方法,替换render为自定义版本 export * from '@testing-library/react'; export { customRender as render };
- 在
jest.config.js中配置全局初始化文件:
module.exports = { // 其他Jest配置... setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'], };
之后测试时无需手动包裹,直接调用render即可:
describe('RegionDetails', () => { test('Region Details', () => { render(<RegionDetail title="test" />); }); });
提示:如果项目使用了自定义Grommet主题,可在全局包裹的
<Grommet>组件中传入theme属性,保证测试环境与生产环境主题一致。
内容的提问来源于stack exchange,提问作者hammygoonan
相关产品推荐
相关产品推荐

