Prevent any routing misfortune in your React app

Laurent Ros
Jan 8, 2019 · 2 min read

A few weeks ago, my team suffered a regression: one developer decided to re-order all the routes alphabetically and one page was not rendered anymore.

We are currently using react-router-dom v4.3.1 and before the regression, our code basically looked like:

On the React Router documentation, you can read: Switch renders the first child <Route> or <Redirect> that matches the location.

The second path="/posts" is here more generic and goes first alphabetically. Therefore, after re-ordering the routes, the component rendered on a route like posts/post/8 was AllPosts, instead of SpecificPost. Hence our regression.

We could have used exact on <Route exact path="/posts" component={AllPosts} /> but that would mean that routes like posts/blablabla would not be matched: the AllPosts component would not be our fallback on those routes anymore.

Should we test this?

The code looked purely declarative to us, but the fact is that it contains logic.
For instance, there is logic in the order of declaration of the <Route>’s: the app does not render the same one way or the other. This component should therefore be tested.

Indeed, testing it brings multiple benefits:

  • it raises the alarm in case of regressions
  • it saves us time by not having to test all the cases manually every time (less frustrating and time effective)
  • it documents the components rendered by the routes and their edge cases for new developers coming in

I however looked it up, and found no official nor clear way to test this.

How do we test this?

To be a good test, it must fill in some requirements. It should be:

  • Robust: We are testing the behavior and not the implementation. It should not care about what’s inside the rendered component (I don’t want to have to mock all of react-intl, redux states … for each component. And the test results should not be impacted by those)
  • Useful: raise an error when the rendered component is not the one expected
  • Fast

Therefore, we didn’t want to render the real pages in the test (they require a lot of data and are quite long to render).
So we jest.mock’ed all of our pages imports, replacing them with simple <div id="myPageName" /> that we’ll use to test.
Here is our solution for the testing of our <Switch> component:

That’s it! Tell me what you think about it ;)

PS: If you don’t want to test this component and make it entirely declarative, you can for instance have a default fallback component, like a 404 page, and set all the other routes as exact .

Laurent Ros

Written by

@lros_8 • Lean Full Stack Developer & Software Architect @Sipios_Fintech • PWA passionate • Climbing addict!

Sipios

Sipios

Sipios conceives and develops tailored products in record time that shape tomorrow’s financial industry. We take on our clients’ most exciting technical and business challenges which we share in our publications.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade