在Enzyme测试中何时使用Component.WrappedComponent及contextTypes报错问题
Enzyme浅渲染报错:
Cannot read property 'contextTypes' of undefined 及 WrappedComponent 使用指南 问题描述
我尝试用Enzyme的浅渲染写测试用例,参考了项目里其他组件的可行模式:
describe('>> MyComponent - Render', () => { let wrapper; beforeEach(() => { wrapper = shallow(<MyComponent.WrappedComponent actions={{}} history={} />); }); it("test something", () => { expect(wrapper).toEqual(1); }); });
但运行时抛出错误:Cannot read property 'contextTypes' of undefined,想搞清楚两个问题:
- 在Enzyme测试里什么时候该用
Component.WrappedComponent? - 怎么解决这个报错?
一、什么时候用WrappedComponent
WrappedComponent是高阶组件(HOC)包装后的组件才会有的属性。举个常见例子:
- 当你用
react-redux的connect、react-router的withRouter,或者自定义HOC包裹组件时,你导出的其实是HOC返回的"增强版"组件,而你写的原始组件会被挂载到这个增强组件的WrappedComponent属性上。
这种场景下,如果你想跳过HOC的逻辑,直接测试原始组件的核心功能(比如不需要模拟redux store、路由上下文这些HOC依赖的东西),就可以通过MyComponent.WrappedComponent拿到原始组件来测试。
但如果你的组件根本没被HOC包裹,直接导出的就是原始组件,那MyComponent.WrappedComponent就是undefined——这大概率是你报错的原因。
二、解决contextTypes未定义的报错
根据你的组件情况,分两种场景处理:
场景1:MyComponent确实被HOC包裹了
首先确认你的组件导出逻辑,比如是不是类似这样:
// MyComponent.js class MyComponent extends React.Component { /* 组件逻辑 */ } // 用connect HOC包裹后默认导出 export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);
如果是这种情况,先排查以下几点:
- 导入是否正确:确保你是默认导入
MyComponent(import MyComponent from './MyComponent'),而不是命名导入(import { MyComponent } from './MyComponent'),否则拿不到WrappedComponent属性。 - 模拟props是否合法:你代码里的
history={}其实传了一个空对象?如果原始组件依赖history的某些方法,可能会出问题;另外如果原始组件不需要history,就别传这个props。 - Enzyme适配器配置:检查你的测试配置文件(比如
setupTests.js)是否正确配置了对应React版本的适配器:import Enzyme from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; // 根据你的React版本选择,比如react-17、react-18 Enzyme.configure({ adapter: new Adapter() });
场景2:MyComponent没有被HOC包裹
这种情况下直接去掉.WrappedComponent,渲染原始组件即可,同时注意修正不合理的断言(你原代码里expect(wrapper).toEqual(1)肯定会失败,wrapper是Enzyme的组件实例,和数字1完全不匹配):
describe('>> MyComponent - Render', () => { let wrapper; beforeEach(() => { // 给history传一个模拟的对象,或者如果组件不需要就删掉这个props wrapper = shallow(<MyComponent actions={{}} history={{ push: jest.fn() }} />); }); it("should render without crashing", () => { // 合理的断言:检查组件是否成功渲染 expect(wrapper.exists()).toBe(true); }); });
内容的提问来源于stack exchange,提问作者Liutong Chen
相关产品推荐
相关产品推荐

