简体   繁体   English

如何使用React和Redux测试具有嵌套容器的组件?

[英]How to test a component with a nested container with React and Redux?

Due to the complexity of the application I am working on I have decided on using a nested redux container rather than passing an action as a prop down to the child components. 由于我正在处理的应用程序的复杂性,我决定使用嵌套的redux容器,而不是将一个动作作为prop传递给子组件。 However, this has proved to be problematic for unit testing when rendering the OuterContainer with jsdom in combination with mocha , chai and sinon . 然而,当使用jsdom结合mochachaisinon渲染OuterContainer时,这证明对于单元测试是有问题的。

Here is a contrived example of the view structure: 这是一个人为的视图结构示例:

<OuterContainer>
  <div>
    <InnerContainer />
  </div>
</OuterContainer>

where OuterContainer & InnerContainer are wrapped with connect. 其中OuterContainerInnerContainer用连接包裹。 eg: 例如:

export connect(<mapStateToProps>)(<Component>)

When running tests the error I am getting is: Invariant Violation: Could not find "store" in either the context or props of "Connect(Component)". Either wrap the root component in a `<Provider>`, or explicitly pass "store" as a prop to "Connect(Component)". 运行测试时,我得到的错误是: Invariant Violation: Could not find "store" in either the context or props of "Connect(Component)". Either wrap the root component in a `<Provider>`, or explicitly pass "store" as a prop to "Connect(Component)". Invariant Violation: Could not find "store" in either the context or props of "Connect(Component)". Either wrap the root component in a `<Provider>`, or explicitly pass "store" as a prop to "Connect(Component)".

Is there a way to unwrap or stub the InnerContainer for unit testing without having to use shallow rendering? 有没有办法解开或存根InnerContainer进行单元测试而不必使用浅层渲染?

Wrap your component in <Provider> when testing. 测试时将组件包装在<Provider> It's up to you whether to supply a real store or a mock with { dispatch, getState, subscribe } to it. 是否提供真实商店或带有{ dispatch, getState, subscribe }取决于您。 Wrapping the outermost component in <Provider store={store}> will also make the store available to the child components at any level of nesting—just like in the app itself. <Provider store={store}>包装最外层组件也将使存储可用于任何嵌套级别的子组件 - 就像在应用程序本身中一样。

const store = createStore(reducer) // can also be a mock
ReactTestUtils.renderIntoDocument(
  <Provider store={store}>
    <OuterContainer />
  </Provider>
)

Another approach is to export both the component to be connected and the container. 另一种方法是导出要连接的组件和容器。 The container as default, of course. 当然,容器是默认的。

export const Comp = (props) => (<p>Whatever</p>)
export default connect(...)(Comp)

Hence, you can unit test Comp . 因此,您可以单元测试Comp

Not sure if this is what your problem is, but I'm sure this will probably help a few people out there looking at this feed. 不确定这是不是你的问题,但我相信这可能会帮助那些看这个饲料的人。

I had the same error and it was a simple fix: 我有同样的错误,这是一个简单的修复:

I had forgotten to pass my component my store object in my entry file (using webpack). 我忘了在我的条目文件中传递我的组件我的商店对象(使用webpack)。

I just added an attribute to the Root component "store={store}" see below: 我刚刚在Root组件“store = {store}”中添加了一个属性,如下所示:

    document.addEventListener("DOMContentLoaded", () => {
      const store = configureStore();
       ReactDOM.render(<Root store={store} />, 
     document.getElementById('content'));
    });

This was my root file code for reference as well: 这是我的根文件代码以供参考:

    import React from 'react';
    import { Provider } from 'react-redux';
    import App from './app';

    const Root = ({ store }) => (
     <Provider store={ store }>
        <App />
     </Provider>
    );

export default Root; export default root;

Hope that helps someone! 希望有人帮助!

Mock the Provider component to return the child component. 模拟Provider组件以返回子组件。

Add this before describe() . describe()之前添加它。

jest.mock('Provider', () => ({children}) => children);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM