How to test react-router with enzyme How to test react-router with enzyme reactjs reactjs

How to test react-router with enzyme


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 />}/>


I had my paths defined in another file for the dynamic router, so I am also testing that all the routes I am rendering as Routes are defined in my paths.js constants:

it('Routes should only have paths declared in src/routing/paths.js', () => {  const isDeclaredInPaths = (element, index, array) => {    return pathsDefined.indexOf(array[index]) >= 0;  }  expect(routesDefined.every(isDeclaredInPaths)).to.be.true;});


This will only pass if the component is rendered successfully:It works with Redux and react-router including hooks.

import React from "react";import { expect } from "chai";import { mount } from "enzyme";import { MemoryRouter, Route } from "react-router-dom";import { createMockStore } from "redux-test-utils";import { Provider } from "react-redux";...describe("<MyComponent />", () => {    it("renders the component", () => {    let props = {      index: 1,      value: 1    };    let state = {};    const wrapper = mount(      <Provider store={createMockStore(state)}>        <MemoryRouter initialEntries={["/s/parameter1"]}>          <Route path="/s/:camera">            <MyComponent {...props} />          </Route>        </MemoryRouter>      </Provider>    );    expect(wrapper.find(ProcessedFrames.WrappedComponent)).to.have.lengthOf(1);  });});