Testing React Router Children with react testing Library

Seyi Oladele
Help Me, I am Stuck
2 min readFeb 28, 2022

“Yes, I know this is half baked but I promised an article this month”

Picking up React can be really fun, till you have to do stuff like testing. React testing library is a great tool to write UX focused tests. This article will assume you just picked up React and understand basic testing.

Let’s assume you have an app component written like so;

import React from "react";import { Routes, Route } from "react-router-dom";import { Home, RouteError} from "./containers";const App = ()  => (<Routes>
<Route path="/" element={<Home />} />
<Route path="*" element={<RouteError />} /></Routes>);export default App;

Assuming your RouteError Component is ;

And you write the test like so.

import React from "react";
import { render, screen } from "@testing-library/react";
import RouteError from "./";
describe("Not found Tests", () => {
test("should test the 404 Page", () => {
render(<RouteError />);
const headerElement = screen.getByText(/This page doesn't seem to exist./);
const bottomLink = screen.getByRole("link");
expect(headerElement).toBeInTheDocument();
expect(bottomLink).toHaveAttribute("href", "/");
});
});

This should be fine, right?

Unfortunately, this test would fail. You will soon be familiar with this error message. “ useHref() may be used only in the context of a <Router> component.

The problem is, you are calling a <Link /> component outside of a Router parent and this to the gods of React is just unacceptable.

Your first thought may be to rewrite the “render” line to look somewhat similar to the snippet below, which will still fail.

The correct way to test children of the <Router> is to wrap them in an instance of <Router> like so;

import React from "react";import { render, screen } from "@testing-library/react";import { MemoryRouter } from "react-router-dom";import RouteError from "..";describe("Not found Tests", () => {test("should test the 404 Page", () => {render(   <MemoryRouter>     <RouteError />   </MemoryRouter>);const headerElement = screen.getByText(/This page doesn't seem to exist./);
const bottomLink = screen.getByRole("link");
expect(headerElement).toBeInTheDocument();
expect(bottomLink).toHaveAttribute("href", "/");
});

You can write this cleaner as shown in the gist below.

--

--