【问题标题】:Testing connected react component that needs params测试需要参数的连接反应组件
【发布时间】:2017-01-15 05:55:16
【问题描述】:

我正在尝试测试一个连接的反应组件,该组件需要一个 props.params.id 来调用动作创建者。当我尝试测试组件是否已连接到商店时,我得到“未捕获的类型错误:无法读取未定义的属性 'id'”

ReactDOM.render(
  <Provider store={store}>
    <Router history={history}>
      <Route path="/" component={App}>
        <IndexRoute component={PostsIndex}/>
        <Route path="posts/:id" component={ShowPost}/>
      </Route>
    </Router>
  </Provider>
  , document.querySelector('.container'));


describe('ConnectedShowPost', ()=> {
    let initialState = {
      posts: { postsList: postsListData, post: postData, error: '' },
      comments: {showComments: false},
      auth: {authenticated: true}
    };

    store = mockStore(initialState);

    connectedShowPost = TestUtils.renderIntoDocument(<Provider store={store}><ConnectedShowPost/></Provider>);
    showPost = TestUtils.scryRenderedComponentsWithType(connectedShowPost, ShowPost)[0];


    expect(showPost.props.posts.post).toEqual(postData);
  })

我尝试在 store 中包含 params,但这不起作用,因为在组件内部使用 params 时没有连接到 store。

我也尝试过将它作为 ownProps 参数传递,但也没有用。

将其作为道具传递给 ConnectedShowPost 组件会导致商店中的所有其他状态项未定义..

还尝试直接设置 showPost.props.params = {id: '123} 这也没有用..

关于如何让这个测试发挥作用的任何想法?

【问题讨论】:

  • 当你说传递一个 ownProps 你的意思是这样做吗?
  • 不,我的意思是连接例如:mapStateToProps(state, ownProps) { id: ownProps.params.id}
  • 我认为如果你指定一个道具对象(类似于初始状态),将它应用到 ConnectedShowPost 像这样: 它会工作。但是,我认为您还应该考虑如何进行测试。在 Redux 文档redux.js.org/docs/recipes/WritingTests.html 中,建议测试“未连接”组件,然后指定接收的道具。这使您可以根据应用程序的状态单独对组件的功能进行单元测试。
  • 这似乎可行,但我认为它不能证明状态是从 mockStore 传递的,而是从我们从传播运算符传递的 props 对象传递的。由于测试了未连接的组件,您是对的。现在这让我很难过
  • 你的props.params.id不会与initialState相关。 initialState 正在被传递到 Redux 存储中。但是 react-router 不使用这个存储 - 它直接将参数传递给您要求它根据路径渲染的组件。因此,在测试中,您必须将这些参数直接传递给组件。我想也可以以某种方式指定window.url,将您的测试包装在&lt;Router&gt; 中并尝试使用它来传递参数...但我认为您会发现更有益的测试来消除这个复杂化并测试组件本身。

标签: javascript reactjs mocha.js redux karma-mocha


【解决方案1】:

如果您连接的组件收到这样的参数:

function mapStateToProps(state, ownProps)
{
    const { match: { params } } = ownProps;
    console.log(params.id);

    return {
         ......
    };
}

然后,在您的测试中,可以将该参数作为传统道具注入。查看下一个示例:

    wrapper = mount(
        <MemoryRouter>
            <ConnectedContainer
                store={store}
                match={
                    {
                        params: {
                            id: 1
                        }
                    }
                }
            />
        </MemoryRouter>
    );

【讨论】:

    猜你喜欢
    • 2021-05-13
    • 1970-01-01
    • 2018-01-30
    • 1970-01-01
    • 1970-01-01
    • 2018-05-13
    • 2014-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多