【问题标题】:With react-router, how do you test for a connected component?使用 react-router,您如何测试连接的组件?
【发布时间】:2018-07-12 13:22:34
【问题描述】:

我正在使用酶和代码进行测试。我正在尝试测试由 react-router-dom 生成的路由。只要路线是未装饰的“未连接”路线,我就没有任何问题。但是如果路由是“连接的”redux 路由,测试就会失败。首先是我的 Routes 组件。

请注意,<PrivateRoute /> 只是一个 HOC,它在发送路由之前首先检查用户是否被授权。为了我要测试的内容,您可以将它们视为来自 react-router-dom 的任何其他 <Route />

const Routes = () => {
  return (
    <Switch>
      <Route exact path='/' component={WelcomeScreen} />
      <Route path='/auth' component={Authorize} />
      <PrivateRoute path='/text_editor' component={TextEditor} />
      <PrivateRoute path='/files' component={FileSearch} />
      <Route component={SplashPage} />
    </Switch>
  )
}

这是我的“未装饰”路线之一的测试。 此测试通过,没有任何问题

 it('should direct to the home page', () => {
    const wrapper = mount(
      <MemoryRouter initialEntries={['/']}>
        <Routes />
      </MemoryRouter>
    )
    expect(wrapper.find('WelcomeScreen')).to.have.length(1);
  })

但是,当我在连接的路由上运行相同的测试时......

it('should direct to the authorized page', () => {
    const wrapper = mount(
      <MemoryRouter initialEntries={['/auth']}>
        <Routes />
      </MemoryRouter>
    )
    expect(wrapper.find('Connect(Authorized')).to.have.length(1);
  })

测试因错误而崩溃:

不变违规:在上下文中找不到“商店”或 “连接(授权)”的道具。要么将根组件包装在 , 或明确地将“商店”作为道具传递给 “连接(授权)”。

所以我使用 redux-mock-store 重构了测试以包含一个 mockStore...

 it('should direct to the authorize page', () => {
    const mockStore = configureStore()
    const store = mockStore({ state: '' })

    const component = mount(
      <Provider store={store}>
        <MemoryRouter initialEntries={['/auth']}>
          <Routes />
        </MemoryRouter>
      </Provider>
    )

    expect(component.find('Connect(Authorize)')).to.have.length(1);
  })

但现在我的错误信息是:

TypeError:无法将对象转换为原始值

我现在不知道如何将商店传递给连接的组件以测试它的存在?有人对测试连接路由的最佳方法有任何想法吗?

【问题讨论】:

    标签: unit-testing redux react-router


    【解决方案1】:

    Enzyme 的坐骑进行了完整的渲染。它比浅层慢得多,并且除了组件本身之外还呈现任何子级。如您所见,完整的渲染还需要为组件可能需要的所有内容提供模拟。 像这样调用 mount 最终比单元测试更接近端到端测试。

    单元测试实际上是关于测试特定于该组件的内容。在这种情况下,您只需要测试您是否正确配置了 Route 元素。任何子组件都有自己的测试,Switch 和 Route 应该在它们所在的库中进行测试。

    这是我如何对类似组件进行单元测试的示例:

    // users.js
    import * as React from 'react';
    import { Route, Switch } from 'react-router-dom';
    
    import EditUser from './editUser';
    import UserList from './userList';
    
    export default function Users() {
      return (
        <Switch>
          <Route exact={true} path="/users" component={UserList}/>
          <Route exact={true} path="/users/createuser" component={EditUser}/>
          <Route path="/users/:id" component={EditUser}/>
        </Switch>
      );
    }
    
    
    // users.test.js
    import { shallow } from 'enzyme';
    import * as React from 'react';
    
    import EditUser from './editUser';
    import UserList from './userList';
    import Users from './users';
    
    describe("Users", () => {
    
      describe('component', () => {
    
        let element;
    
        beforeEach(() => {
          element = <Users />
        });
    
        it('renders as expected', () => {
          const component = shallow(element);
          expect(component).toMatchSnapshot();
        });
    
        it('routes /users to UserList', () => {
          const component = shallow(element);
          expect(component.find('Route[exact=true][path="/users"]').first().prop('component')).toBe(UserList);
        });
    
        it('routes /users/createuser to EditUser', () => {
          const component = shallow(element);
          expect(component.find('Route[exact=true][path="/users/createuser"]').first().prop('component')).toBe(EditUser);
        });
    
        it('routes /users/:id to EditUser', () => {
          const component = shallow(element);
          expect(component.find('Route[path="/users/:id"]').first().prop('component')).toBe(EditUser);
        });
    
      });
    
    });
    

    像这样的单元测试只针对组件本身,使您的测试保持独立、有针对性和快速。您可以确保在端到端测试中将所有内容组合在一起并作为一个整体正常运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-13
      • 2015-10-12
      • 2019-02-15
      • 1970-01-01
      • 1970-01-01
      • 2020-12-02
      • 2017-03-29
      相关资源
      最近更新 更多