【问题标题】:How to test a component with a nested container with React and Redux?如何使用 React 和 Redux 测试带有嵌套容器的组件?
【发布时间】:2016-03-23 10:33:30
【问题描述】:

由于我正在处理的应用程序的复杂性,我决定使用嵌套的 redux 容器,而不是将操作作为道具传递给子组件。然而,当渲染OuterContainerjsdom 并结合mochachaisinon 时,这已被证明是单元测试的问题。

这是一个人为的视图结构示例:

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

OuterContainerInnerContainer 用连接包裹。例如:

export connect(&lt;mapStateToProps&gt;)(&lt;Component&gt;)

运行测试时,我得到的错误是: 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)".

有没有办法解包或存根 InnerContainer 以进行单元测试,而不必使用浅层渲染?

【问题讨论】:

    标签: javascript reactjs mocha.js redux jsdom


    【解决方案1】:

    测试时将您的组件包装在&lt;Provider&gt; 中。是否提供真实商店或带有{ dispatch, getState, subscribe } 的模拟商店取决于您。将最外层组件包裹在 &lt;Provider store={store}&gt; 中也会使 store 可用于任何嵌套级别的子组件——就像在应用程序本身中一样。

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

    【讨论】:

    • 太棒了!感谢您的建议。现在试一试:)
    • 像魅力一样工作。再次感谢@DanAbramov!
    • @dan-abramov:这行得通。但是,它不再是真正的单元测试。 Enzyme 有shallow,但它仍然深入到一个连接的子组件。你知道是否可以只测试&lt;InnerContainer /&gt; 是否存在而不渲染它?
    • 我回应@publicJorn 的关注。我自己喜欢这个解决方案,但它使测试变得比应有的复杂。
    【解决方案2】:

    另一种方法是同时导出要连接的组件和容器。当然,容器是默认的。

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

    因此,您可以对Comp 进行单元测试。

    【讨论】:

    • 但这违背了用完整的 Redux 链接测试组件的目的。不会吗?
    • @shobhit1 但是你正在测试你的组件和connect,它已经被react-redux 测试过了。不坏,也不好。那你只是过度测试了。
    • 如果Comp 本身导入并使用另一个容器,这将不起作用。然后子容器会期望store 存在,并且测试将失败。
    【解决方案3】:

    不确定这是否是您的问题,但我相信这可能会帮助一些正在查看此提要的人。

    我遇到了同样的错误,这是一个简单的修复:

    我忘记在我的入口文件中传递我的组件我的 store 对象(使用 webpack)。

    我刚刚向根组件“store={store}”添加了一个属性,如下所示:

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

    这也是我的根文件代码供参考:

        import React from 'react';
        import { Provider } from 'react-redux';
        import App from './app';
    
        const Root = ({ store }) => (
         <Provider store={ store }>
            <App />
         </Provider>
        );
    

    导出默认根目录;

    希望对某人有所帮助!

    【讨论】:

      【解决方案4】:

      模拟Provider 组件以返回子组件。

      describe()之前添加这个。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-14
        • 2019-05-26
        • 2016-09-26
        • 1970-01-01
        • 2015-07-19
        • 2020-06-21
        • 2019-06-14
        • 1970-01-01
        相关资源
        最近更新 更多