If you are using react router dom, then there are two ways to test the routes using jest.

One way is to create an object containing the pathname of route as key and component name for that route as value, and then do an assertion based on that object.

Other way is to use the memory router and pass the initial state to it, and then do assertion for it. We will look into both of these ways, and see which one to use to test what kind of routes.

Testing routes using an object of path name and component name

In this scenario, we will iterate through all the routes, then get the route path name and the component name corresponding to that path in an object. Once we have the object, we can easily assert if the path matches correctly with the component. The only downside to this testing is you cannot test the routes which do not have the pathname, like the non matching 404 route.

Lets see some example. Here is the component containing the routes. We are going to test this component.

Routes.jsx

import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'

export class Home extends Component{
    render(){
        return(
            <div>Home Page</div>
        )
    }
}

export const News = (props)=>{
    const {location} = props;
    return <div>News Feed {location.pathname}</div>
}

export class NoMatch extends Component{
    render(){
        return(
            <div>404 page</div>
        )
    }
}

class Routes extends Component{

  render(){
    return(
      <div>
        <Router>
            <Route exact path="/" component={Home}/>
            <Route exact path="/news" component={News}/>
            <Route exact path="/news/techdomain" component={News}/>
            <Route component={NoMatch} />
            <Link to="/" >Home page</Link><br/>
            <Link to="/news">News page</Link><br/>
            <Link to="/news/techdomain">News page for techdomain </Link>
        </Router>
      </div>
    )
  }
}

export default Routes;

In order to get the object containing the pathname as key and componentname as value, we will iterate through the children of the Router component and get all the routes.

const component = shallow(<Routes/>);
pathMap = component.find(Route).reduce((pathMap, route) => {
    const routeProps = route.props();
    pathMap[routeProps.path] = routeProps.component;
    return pathMap;
}, {});

So the pathMap object is like this

{
  '/': [Function: Home],
  '/news': [Function: News],
  '/news/techdomain': [Function: News],
  undefined: [Function: NoMatch] 
}

Here is the test file containing the full code.

routes.test.js

import React from 'react';
import { shallow, mount } from 'enzyme';
import Routes, { Home, News, NoMatch } from './Routes';
import { MemoryRouter
} from 'react-router'
import { Route } from 'react-router-dom';

let pathMap = {};
describe('routes using array of routers', () => {
  beforeAll(() => {
    const component = shallow(<Routes/>);
    pathMap = component.find(Route).reduce((pathMap, route) => {
        const routeProps = route.props();
        pathMap[routeProps.path] = routeProps.component;
        return pathMap;
      }, {});
      console.log(pathMap)
  })
  it('should show Home component for / router (getting array of routes)', () => {

    expect(pathMap['/']).toBe(Home);
  })
  it('should show News Feed component for /news router', () => {
    expect(pathMap['/news']).toBe(News);
  })
  it('should show News Feed component techdomain for /news router', () => {
    expect(pathMap['/news/techdomain']).toBe(News);
  })
  it('should show No match component for route not defined', ()=>{
      expect(pathMap['undefined']).toBe(NoMatch);
  })
})

So as you can see, we are testing the component using the object pathMap. To test if the Home component is actually mapped to / route, assert it as follows

expect(pathMap['/']).toBe(Home);

Similarly to assert if the News component is mapped to /news route, assert it in similar way

expect(pathMap['/news']).toBe(News);

And because there is no route defined for the 404 component, it will be matched to any route that is not handled. So if you open /abc route, then it will be handled by NoMatch component. Because there is no route defined for NoMatch component, it will be undefined. So to test if our 404 component (NoMatch component) is mapped as the last component, we have to assert it to the undefined.

expect(pathMap['undefined']).toBe(NoMatch);

There is better way to test this NoMatch component using the MemoryRouter. We will see how to test the same Routes component using the memory router in next post.