React + Redux + react-router: how to test routing

At my company, we have built quite a large single-page application using TypeScript, React and Redux. For routing, we are using react-router library by React Training. Everything works great except we had a hard time writing tests for routing (for testing, we use Enzyme with Jest). React is a very simple and rather minimalistic library, so once you have assembled your lego of various libraries, certain kinds of integration testing for your particular combination may get tricky. In this post, I will very briefly go over the routing testing solution I have come up with.

If your container makes decisions based on the react-router’s match object, you need to populate the container’s match with fixture data. This can be achieved in various ways, the simplest of which is to wrap the container in a Route element from react-router. If you feel adventurous, you can wrap your container in a simple mock parent container with something like Switch inside. You can also use the actual parent container, depending on the situation.

Redux store is passed into the above through the Provider component from the react-redux library (by Redux.js). All of this you can wrap in MemoryRouter —it allows for mocking history and navigation. You can set its initialEntries (sort of a navigation history mock) and initialIndex (this is a point in the navigation history where your test will start). To illustrate, this is the little helper function I wrote (the purpose of actionInterceptor is to test dispatching actions and/or custom middlewares, while we’re at it):

Pretty straightforward. Now, to assert on the location changes, you need to find your trigger element in the wrapper, simulate the event, and then either intercept your dispatched actions with a mock middleware, or examine the router’s location object.