如何在构造函数内部使用上下文的情况下使用 jest 和酶来测试反应上下文?
Posted
技术标签:
【中文标题】如何在构造函数内部使用上下文的情况下使用 jest 和酶来测试反应上下文?【英文标题】:how to test react-context using jest and enzyme where context is used inside constructor? 【发布时间】:2020-03-02 14:50:58 【问题描述】:我正在使用 react-context 来保存我的数据并访问构造函数中的数据,如下所示:
class MyComponent extends Component
//constructor
constructor(props, context)
super(props, context);
const testData = this.context.storedData
this.state=
//maintained states
//constructor ends
我正在尝试使用 jest 和酶框架测试反应上下文,但得到如下错误:
TypeError: Cannot read property 'testData ' of undefined
25 | constructor(props, context)
26 | super(props, context);
> 27 | const testData = this.context.storedData
| ^
我已经尝试了大多数解决方案,但没有任何效果。我正在寻找适合我情况的完美解决方案。
【问题讨论】:
哇,旧版上下文 API。从未使用过它,您可以考虑转到现代Context API吗? 【参考方案1】:从未使用过旧版上下文,its doc page 相当差。要测试依赖于上下文的组件,您必须传递该上下文,而且选项很少。
-
Enzyme 的
mount()
/shallow()
提供second argument options
,可用于传递上下文。但我不确定它是否适用于旧版上下文
const wrapper = mount(<MyComponent />, context: storedData: testData: 1 );
-
使用额外的包装器来提供上下文:
function createWrapperForContext (contextData)
return class Wrapper extends React.Component
getChildContext()
return contextData;
render()
return this.props.children;
;
....
const ContextWrapper = createWrapperForContext(testData);
const elementWrapper = mount(<ContextWrapper><YourComponent /></ContextWrapper>)
如果可能更喜欢迁移到现代的 Context API,那么它就更少了。
PS 为什么需要在构造函数中访问context
?如果您在 render()
中使用它,您将永远不会担心“上下文已更新,但 render()
仍然引用旧值”。
【讨论】:
感谢@skyboyer 的解决方案我已经尝试过了,但对我没有用。解决我的问题的是:我在 test.js 文件中导入了所需的上下文并将测试写为:test("render", () => const props = //props we need to pass const contextData = //context data we need to pass const wrapper = mount(<ContextName.Provider value=contextData> <ComponentName ...props /></ContextName.Provider>) expect(wrapper.exists()).toBe(true); );
【参考方案2】:
确实,传递带有上下文属性的选项甚至可以修复遗留上下文。
假设我们有color
上下文https://reactjs.org/docs/legacy-context.html。
测试将是:
import shallow, ShallowWrapper from 'enzyme';
import React from 'react';
describe('MyComponent', () =>
let component = ShallowWrapper<MyComponentProps>;
// This will test the default color value
it('should render with default context', () =>
component = shallow(<MyComponent ...props/>);
expect(component).toMatchSnapshot();
);
// testing with different context
it('should render with context', () =>
component = shallow(<MyComponent ...props />,
context:
color: 'red', // you still give it the default value.
,
);
component.setContext( color: 'purple' );
component.instance().forceUpdate(); // you could call also render from instance
expect(component).toMatchSnapshot();
);
);
【讨论】:
以上是关于如何在构造函数内部使用上下文的情况下使用 jest 和酶来测试反应上下文?的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有冲突的情况下将 Mocha 和 Jest 与 TypeScript 一起使用?