Reactjs 在React&;重演
我有一个组件Reactjs 在React&;重演,reactjs,mocha.js,redux,enzyme,Reactjs,Mocha.js,Redux,Enzyme,我有一个组件SampleComponent,它安装了另一个“连接的组件”(即容器)。当我尝试通过mounting测试SampleComponent时(因为我需要componentDidMount),我得到了错误: 不变冲突:在上下文或上下文中找不到“存储” “连接(集装箱组件)”的道具。或者包装根组件 在中,或显式地将“store”作为道具传递给 “连接(集装箱组件)” 测试这一点的最佳方法是什么?我基本上是将我的redux存储(和Provider)放入实用程序组件中,如下所示: export
SampleComponent
,它安装了另一个“连接的组件”(即容器
)。当我尝试通过mount
ing测试SampleComponent
时(因为我需要componentDidMount
),我得到了错误:
不变冲突:在上下文或上下文中找不到“存储”
“连接(集装箱组件)”的道具。或者包装根组件
在中,或显式地将“store”作为道具传递给
“连接(集装箱组件)”
测试这一点的最佳方法是什么?我基本上是将我的
redux
存储(和Provider
)放入实用程序组件中,如下所示:
export const CustomProvider = ({ children }) => {
return (
<Provider store={store}>
{children}
</Provider>
);
};
酶的装载量采用可选参数。你所需要的两件事是
options.context:(对象[可选]:要传递到组件中的上下文
options.childContextTypes:(对象[可选]):包装器所有子级的合并contextTypes
您可以使用如下选项对象装载SampleComponent
:
const store = {
subscribe: () => {},
dispatch: () => {},
getState: () => ({ ... whatever state you need to pass in ... })
}
const options = {
context: { store },
childContextTypes: { store: React.PropTypes.object.isRequired }
}
const _wrapper = mount(<SampleComponent {...defaultProps} />, options)
conststore={
订阅:()=>{},
调度:()=>{},
getState:()=>({…需要传入的任何状态…})
}
常量选项={
上下文:{store},
childContextTypes:{store:React.PropTypes.object.isRequired}
}
常量包装器=装载(,选项)
现在,您的SampleComponent将把您提供的上下文传递给连接的组件
,您可以使用名称导出来解决此问题:
你应该:
class SampleComponent extends React.Component{
...
render(){
<div></div>
}
}
export default connect(mapStateToProps, mapDispatchToProps)(SampleComponent)
并在没有redux存储的情况下导入此组件:
import { SampleComponent } from 'your-path/SampleComponent';
使用此解决方案,您无需将存储导入测试文件。选项1)
您可以在测试中使用React-Redux的提供者组件包装容器组件。因此,使用这种方法,您实际上引用了存储,将其传递给提供者,并在内部组成您的测试组件。这种方法的优点是您实际上可以为测试创建一个自定义存储。如果您想测试组件中与Redux相关的部分,这种方法非常有用
备选方案2)
也许你不在乎测试Redux相关的部分。如果您只是对测试组件的渲染和与本地状态相关的行为感兴趣,那么只需为组件的未连接普通版本添加命名导出即可。为了澄清一下,当你把“export”关键字添加到你的类中时,你基本上是说现在这个类可以用两种方式导入,要么用大括号{},要么不用大括号。例如:
export class MyComponent extends React.Component{ render(){ ... }}
...
export default connect(mapStateToProps, mapDispatchToProps)(MyComponent)
稍后在您的测试文件上:
import MyComponent from 'your-path/MyComponent'; // it needs a store because you use "default export" with connect
import {MyComponent} from 'your-path/MyComponent'; // don't need store because you use "export" on top of your class.
@anyOldClassDecorator
export class AnyOldClass {
@anyOldMethodDecorator
method() {
console.log('hello');
}
}
@anyOldClassDecorator
export class AnyOldClass {
@anyOldMethodDecorator
method() {
console.log('hello');
}
}
export class __undecorated__AnyOldClass {
method() {
console.log('hello');
}
}
我希望能帮助任何人。为了使decorator语法的使用更易于测试,我做了以下几点: 输入:
import MyComponent from 'your-path/MyComponent'; // it needs a store because you use "default export" with connect
import {MyComponent} from 'your-path/MyComponent'; // don't need store because you use "export" on top of your class.
@anyOldClassDecorator
export class AnyOldClass {
@anyOldMethodDecorator
method() {
console.log('hello');
}
}
@anyOldClassDecorator
export class AnyOldClass {
@anyOldMethodDecorator
method() {
console.log('hello');
}
}
export class __undecorated__AnyOldClass {
method() {
console.log('hello');
}
}
输出:
import MyComponent from 'your-path/MyComponent'; // it needs a store because you use "default export" with connect
import {MyComponent} from 'your-path/MyComponent'; // don't need store because you use "export" on top of your class.
@anyOldClassDecorator
export class AnyOldClass {
@anyOldMethodDecorator
method() {
console.log('hello');
}
}
@anyOldClassDecorator
export class AnyOldClass {
@anyOldMethodDecorator
method() {
console.log('hello');
}
}
export class __undecorated__AnyOldClass {
method() {
console.log('hello');
}
}
希望这能提供一个可靠的选项3 还可以选择使用 用于测试Redux异步操作创建者和中间件的模拟存储。模拟存储区将创建一个调度操作数组,作为测试的操作日志 模拟存储区在存储区对象上提供了Redux所需的必要方法。 您可以指定可选的中间件和特定于应用程序的初始状态
import configureStore from 'redux-mock-store'
const middlewares = []
const mockStore = configureStore(middlewares)
const initialState = {}
const store = mockStore(initialState)
const wrapper = mount(<SampleComponent store={store}/>)
从“redux模拟存储”导入配置存储
const middleware=[]
const mockStore=configureStore(中间件)
常量initialState={}
常量存储=模拟存储(初始状态)
const wrapper=mount()
我看到您正在使用mount,如果我试图用shallo
替换mount
,我会得到一个错误。您也遇到过这种情况吗?虽然这个答案在某些情况下有效,但当您需要测试组件的生命周期时,它就不起作用了。例如,调用wrapper.setProps()
不会在SampleComponent
上触发componentWillReceiveProps()
。这太完美了!虽然公认的答案在大多数情况下都有效,但缺点是您无法充分使用mountapi。例如,使用在提供程序中包装组件的公认答案将不允许使用wrapper.state()
api。此解决方案将为您的包装提供完整的方法。这是一个比公认的答案更好的答案,原因如下(即,您安装的包装实际上不是您尝试测试的组件),并且还因为您可以使用模拟存储而不是实际存储,将所有redux都排除在等式之外。此可选参数不在文档中,您是如何找到它的?在代码中?如果SampleComponent
使用一个名为SubComponent
的连接组件,并且我们希望使用mount
检查它是否正确呈现(集成测试,而不是单元),该怎么办?您可以将存储作为第二个参数传递给SampleComponent
,但是SubComponent
将没有存储。由于Ezyme v3,浅层调用ComponentDidMount FYI