【问题标题】:How can I correctly test my App component to verify that the routes are rendering the correct components如何正确测试我的 App 组件以验证路由是否呈现正确的组件
【发布时间】:2020-12-11 13:34:33
【问题描述】:

在我的 App 组件中,我有一堆渲染各自组件的路由,我想测试这些路由是否渲染了正确的组件。

App.js

export default () => {
    return (
        <BrowserRouter>
            <div>
                <Navbar />
            
                <Switch>
                    <Route exact path='/' component={Home} />
                    <Route exact path='/signup' component={Signup} />
                    <Route exact path='/signin' component={Signin} />
                    <Route exact path='/profile' component={Profile} />
                </Switch>
            </div>
        </BrowserRouter>
    );
};

在互联网上阅读了一些内容并遵循了一些 tuts 之后,我了解到我可以使用 MemoryRouter 检查某个组件是否与给定路由匹配,如果匹配,它应该返回一个或长度值 1。

App.test.js

import React from 'react';
import {  mount } from 'enzyme';
import { MemoryRouter } from 'react-router';

import App from './App';
import { Home } from './home/Home';
import Signup from './auth/signup/Signup';
import Signin from './auth/signin/Signin';

describe('routes using memory router', () => {
    it('should show <Home /> component for "/" route', () => {
        const component = mount(<MemoryRouter initialEntries={["/"]}><App /></MemoryRouter>);

        expect(component.find(Home)).toHaveLength(1);
    });

    it('should show <Signup /> component for "/signup" route', () => {
        const component = mount(<MemoryRouter initialEntries={["/signup"]}><App /></MemoryRouter>);

        expect(component.find(Signup)).toHaveLength(1);
    });

    it('should show <Signin /> component for "/signin" route', () => {
        const component = mount(<MemoryRouter initialEntries={["/signin"]}><App /></MemoryRouter>);

        expect(component.find(Signin)).toHaveLength(1);
    });
});

但完全出乎我的意料,我收到了这个错误,说它找不到商店。对于我要测试的三个路由“/”、“/signup”和“/signin”,该消息重复了 3 次。我刚刚在这里复制了第三条消息。

 Could not find "store" in the context of "Connect(withRouter())". Either wrap the root component
 in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(withRouter())
 in connect options.

      23 |
      24 |     it('should show <Signin /> component for "/signin" route', () => {
    > 25 |         const component = mount(<MemoryRouter initialEntries={["/signin"]}><App /></MemoryRouter>);
         |                           ^
      26 |
      27 |         expect(component.find(Signin)).toHaveLength(1);
      28 |     });

基于上述方法,我如何正确测试路由是否呈现正确的组件?我应该提到这是我第一次测试,所以我正在努力学习。如果我的问题不清楚,我深表歉意。任何答案或链接,甚至另一种方法都将不胜感激。

解决商店问题后的新错误

● renders correct routes › should show <Signup /> component for "/signup" route

    expect(received).toHaveLength(expected)

    Expected length: 1
    Received length: 0
    Received object: {}

      40 |         );
      41 |
    > 42 |         expect(wrapper.find(Signup)).toHaveLength(1);
         |                                      ^
      43 |     });
      44 |

      at Object.<anonymous> (src/components/App.test.js:42:38)

我在测试的所有路线上都收到了这条消息,我在这里只粘贴了其中一条,除了路线不同之外,它们都是相同的。

【问题讨论】:

    标签: reactjs redux react-router enzyme


    【解决方案1】:

    我认为您忘记将提供程序与商店一起添加。 将更改添加到您的 App.test.js 喜欢这里:

    import React from 'react';
    import {  mount } from 'enzyme';
    import { MemoryRouter } from 'react-router';
    import { Provider } from 'react-redux'
    
    import App from './App';
    import { Home } from './home/Home';
    import Signup from './auth/signup/Signup';
    import rootReducer from './reducer';
    
    describe('routes using memory router', () => {
        let store
        beforeEach(async () => {
            store = createReduxStore(
                rootReducer,
            )
        })
    
        it('should show <Home /> component for "/" route', () => {
            const component = mount(<MemoryRouter initialEntries={["/"]}><Provider store={store}><App /></Provider></MemoryRouter>);
    
            expect(component.find(Home)).toHaveLength(1);
          });
    
        it('should show <Signup /> component for "/signup" route', () => {
            const component = mount(<MemoryRouter initialEntries={["/signup"]}><Provider store={store}><App /></Provider></MemoryRouter>);
    
            expect(component.find(Signup)).toHaveLength(1);
        });
    
        it('should show <Signin /> component for "/signin" route', () => {
            const component = mount(<MemoryRouter initialEntries={["/signin"]}><Provider store={store}><App /></Provider></MemoryRouter>);
    
            expect(component.find(Signin)).toHaveLength(1);
        });
    });
    

    对于新问题:

    不要使用您的提供者包装组件,而是使用wrappingComponent 选项,如下所示:

    function WrapWithProviders({ children }) {
      return (
        <Provider store={store}>
          <MemoryRouter>
            <Switch>
              {children}
            </Switch>
          </MemoryRouter>
        </Provider>
      );
    }
    const wrapper = mount(<TestComponent />, {
      wrappingComponent: WrapWithProviders,
    });
    

    但我不确定,关于这个

    【讨论】:

    • 您好,谢谢您的回答。我听从了你的建议,它解决了商店问题,但现在我得到了一些新东西。我会用我得到的错误更新我上面的问题,也许你知道这是关于什么的。
    • @TarasiCristiAndrei 我在答案中添加了更多信息
    • 太棒了。它确实奏效了。谢谢,我的朋友。它在没有 Switch 的情况下工作。在看到您的解决方案有效后,我开始阅读有关 mount 方法的更多信息,但我仍然不知道第二个参数(对象)是什么。
    猜你喜欢
    • 2018-04-25
    • 2021-09-20
    • 2017-07-21
    • 2015-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    • 1970-01-01
    相关资源
    最近更新 更多