使用React和Redux中的Enzyme进行嵌套组件测试

Det*_*ned 30 mocha.js reactjs redux enzyme

我有一个组件SampleComponent安装另一个"连接组件"(即container).当我尝试SampleComponent通过mounting 测试(因为我需要componentDidMount),我得到错误:

不变违规:无法在"Connect(ContainerComponent)"的上下文或道具中找到"store".将根组件包装在a中,或者将"store"显式传递为"Connect(ContainerComponent)"的prop.

测试这个的最佳方法是什么?

小智 40

酶的安装采用可选参数.你需要的两个是必需的

options.context: (Object [optional]): Context to be passed into the component

options.childContextTypes: (Object [optional]): Merged contextTypes for all children of the wrapper 您可以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)
Run Code Online (Sandbox Code Playgroud)

现在,您的SampleComponent将您提供的上下文传递给connected component.

  • 太棒了!虽然接受的答案大部分时间都有效,但缺点是你无法使用mount api达到最大容量.例如,使用在"Provider"中包装组件的接受答案将不允许使用`wrapper.state()`api.此解决方案将为您的包装提供全方位的方法. (3认同)
  • 这个可选参数不在docs中,你是怎么发现的?在代码中? (3认同)

Det*_*ned 10

我基本上做的是引入我的redux商店(和Provider)并将其包装在实用程序组件中,如下所示:

export const CustomProvider = ({ children }) => {
  return (
    <Provider store={store}>
      {children}
    </Provider>
  );
};
Run Code Online (Sandbox Code Playgroud)

然后,我mountSampleComponent和对其运行测试:

it('contains <ChildComponent/> Component', () => {
  const wrapper = mount(
    <CustomProvider>
      <SampleComponent {...defaultProps} />
    </CustomProvider>
  );
  expect(wrapper.find(ChildComponent)).to.have.length(1);
});
Run Code Online (Sandbox Code Playgroud)

  • 虽然这个答案在某些情况下有效,但是当您需要测试组件的生命周期时,它不起作用.例如,调用`wrapper.setProps()`不会触发`SampleComponent`上的`componentWillReceiveProps()`. (4认同)