Search code examples
reactjsmocha.jsreact-routerchaienzyme

How to test react-router with enzyme


I am using enzyme+mocha+chai to test my react-redux project. Enzyme provides shallow to test component behavior. But I didn't find a way to test the router. I am using react-router as below:

<Router history={browserHistory}>
     ...
        <Route path="nurse/authorization" component{NurseAuthorization}/>
     ...
  </Route>

I want to test this route nurse/authorization refer to NurseAuthorization component. How to test it in reactjs project?

EDIT1

I am using react-router as the router framework.


Solution

  • You can wrap your router inside a component in order to test it.

    Routes.jsx

    export default props => (
      <Router history={browserHistory}>
        ...
        <Route path="nurse/authorization" component{NurseAuthorization}/>
        ...
      </Route>
    )
    

    index.js

    import Routes from './Routes.jsx';
    ...
    
    ReactDOM.render(<Routes />, document.getElementById('root'));
    

    Then you have to shallow render your Routes component, and you are able to create an object map to check the correspondance between path and related component.

    Routes.test.js

    import { shallow } from 'enzyme';
    import { Route } from 'react-router';
    import Routes from './Routes.jsx';
    import NurseAuthorization from './NurseAuthorization.jsx';
    
    it('renders correct routes', () => {
      const wrapper = shallow(<Routes />);
      const pathMap = wrapper.find(Route).reduce((pathMap, route) => {
        const routeProps = route.props();
        pathMap[routeProps.path] = routeProps.component;
        return pathMap;
      }, {});
      // { 'nurse/authorization' : NurseAuthorization, ... }
    
      expect(pathMap['nurse/authorization']).toBe(NurseAuthorization);
    });
    

    EDIT

    In case you want to additionally handle the case of render props:

    const pathMap = wrapper.find(Route).reduce((pathMap, route) => {
      const routeProps = route.props();
      if (routeProps.component) {
        pathMap[routeProps.path] = routeProps.component;
      } else if (routeProps.render) {
        pathMap[routeProps.path] = routeProps.render({}).type;
      }
      return pathMap;
    }, {});
    

    It will work only in case you render directly the component you want to test (without extra wrapper).

    <Route path="nurse/authorization" render{() => <NurseAuthorization />}/>