测试从上下文 api 消耗道具的反应组件期间的不变违规错误
Posted
技术标签:
【中文标题】测试从上下文 api 消耗道具的反应组件期间的不变违规错误【英文标题】:Invariant Violation error during testing react component which consumes prop from context api 【发布时间】:2019-04-02 05:48:05 【问题描述】:我是 jest 和酶的新手,在测试使用 react 上下文 api 中的 prop 的 react 组件时遇到了一些 Invariant Violation 错误。我熟悉 Invariant Violation 错误及其可能的原因,但是,在这种情况下,我被困住了。一些建议非常感谢。这是一个仅用于演示目的的最小代码设置。我在跑步 “酶”:“3.7.0”, “酶适配器反应 16”:“1.6.0”, “笑话”:“23.6.0”。
注意,下面的代码可以正常工作,但是,只有在我尝试测试 MyComponent.jsx 时才会出现问题。
index.jsx
import * as React from 'react';
import ReactDOM from 'react-dom';
import MyComponentWithContext from "./MyComponent";
const testValue = 'test value';
export const MyContext = React.createContext(testValue);
const App = () =>
return (
<div>
<MyComponentWithContext/>
</div>
)
ReactDOM.render(
<MyContext.Provider value=testValue>
<App/>
</MyContext.Provider>,
document.getElementById('root') || document.createElement('div')
)
MyComponent.jsx
import * as React from 'react';
import MyContext from './';
export class MyComponent extends React.Component
constructor(props)
super(props)
getContextValue()
return this.props.testValue
render()
return <div>this.getContextValue()</div>;
const MyComponentWithContext = () => (
<MyContext.Consumer>
testValue => <MyComponent testValue=testValue/>
</MyContext.Consumer>
)
export default MyComponentWithContext;
当我尝试像这样测试 MyComponent 时:
MyComponent.unit.test.js
import React from 'react';
import shallow from 'enzyme';
import MyComponent from '../MyComponent';
describe('<MyComponent />', () =>
const testValue = 'test value';
it('should return test value', () =>
const wrapper = shallow(<MyComponent testValue=testValue/>);
expect(wrapper.instance().getContextValue()).toEqual(testValue);
);
);
这给了我以下错误:
Invariant Violation:元素类型无效:应为字符串(对于内置组件)或类/函数(对于复合组件),但得到:未定义。您可能忘记从定义组件的文件中导出组件,或者您可能混淆了默认导入和命名导入。
检查App
的渲染方法。
| ReactDOM.render(
| ^
18 | <MyContext.Provider value=testValue>
19 | <App/>
20 | </MyContext.Provider>,
【问题讨论】:
我认为组件由于循环依赖而未定义。而真正的问题是根本不应该存在循环依赖。 【参考方案1】:ReactDOM.render(...)
不应在单元测试中进行评估。模块组织不当。 index.js 提供了在单元测试中应该避免的副作用,它还与 MyComponent.js 有不必要的循环依赖,这是可以避免的。
export const MyContext = React.createContext(testValue);
应该移动到单独的模块,所以组件模块可以直接导入。
【讨论】:
以上是关于测试从上下文 api 消耗道具的反应组件期间的不变违规错误的主要内容,如果未能解决你的问题,请参考以下文章
使用 get API 调用反应全局状态/道具(没有 Redux)
React Context API,从子组件设置上下文状态,而不是将函数作为道具传递
JestJS -> 不变违规:在“连接(投资组合)”的上下文或道具中找不到“商店”