How to Test StaticRouter in React
Testing StaticRouter in React is essential for verifying
how your components render during server-side rendering (SSR) or in
stateless environments. This article provides a straightforward guide on
how to configure and write unit tests for components wrapped in
StaticRouter using React Testing Library and Jest, ensuring
your application handles different URL paths correctly without a browser
environment.
Why Test with StaticRouter?
Unlike BrowserRouter, which relies on the browser’s
history API, StaticRouter takes a single, unchanging
location prop. This makes it ideal for testing because you can
explicitly pass any URL to the router and immediately assert that the
correct component renders for that route.
Step-by-Step Implementation
To test components using StaticRouter, you will need to
import it from react-router-dom/server (in React Router v6)
and wrap your main routing component with it in your test file.
1. Install Dependencies
Ensure you have React Testing Library and Jest installed in your project:
npm install --save-dev @testing-library/react @testing-library/jest-dom2. Create the Component to Test
Here is a simple component with multiple routes that we want to test:
// App.jsx
import React from 'react';
import { Routes, Route } from 'react-router-dom';
export const App = () => (
<Routes>
<Route path="/" element={<h1>Home Page</h1>} />
<Route path="/about" element={<h1>About Page</h1>} />
<Route path="*" element={<h1>404 Not Found</h1>} />
</Routes>
);3. Write the Tests
In your test file, import StaticRouter from
react-router-dom/server and pass the target route to the
location prop.
// App.test.jsx
import React from 'react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import { StaticRouter } from 'react-router-dom/server';
import { App } from './App';
describe('App Routing with StaticRouter', () => {
test('renders Home Page when location is "/"', () => {
render(
<StaticRouter location="/">
<App />
</StaticRouter>
);
expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent('Home Page');
});
test('renders About Page when location is "/about"', () => {
render(
<StaticRouter location="/about">
<App />
</StaticRouter>
);
expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent('About Page');
});
test('renders 404 Page on an invalid route', () => {
render(
<StaticRouter location="/unknown-route">
<App />
</StaticRouter>
);
expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent('404 Not Found');
});
});Key Considerations
- Import Path: In React Router v6,
StaticRoutermust be imported fromreact-router-dom/server. If you are still using React Router v5, import it directly fromreact-router-dom. - Stateless Testing:
StaticRoutercannot navigate dynamically in response to user actions like clicking a<Link>. If you need to test user interaction and navigation flows, useMemoryRouterinstead.