How to Test React Router: Simple Guide with Examples
To test
React Router, wrap your components with MemoryRouter from react-router-dom in your tests. Use React Testing Library to render components and simulate navigation, then check if the expected routes and components appear.Syntax
Use MemoryRouter to provide routing context in tests. Wrap your component inside it and set the initial route with initialEntries. Use screen and render from React Testing Library to interact with the rendered output.
MemoryRouter: Router for testing that keeps history in memory.initialEntries: Array of paths to set starting routes.render: Renders React components for testing.screen: Queries the rendered output.
javascript
import { render, screen } from '@testing-library/react'; import { MemoryRouter } from 'react-router-dom'; render( <MemoryRouter initialEntries={["/your-route"]}> <YourComponent /> </MemoryRouter> ); // Then use screen to check elements expect(screen.getByText(/some text/i)).toBeInTheDocument();
Example
This example shows how to test navigation between two routes using React Router and React Testing Library. It verifies that the correct component renders for each route.
javascript
import React from 'react'; import { render, screen } from '@testing-library/react'; import { MemoryRouter, Routes, Route, Link } from 'react-router-dom'; function Home() { return <h1>Home Page</h1>; } function About() { return <h1>About Page</h1>; } function App() { return ( <> <nav> <Link to="/">Home</Link> <Link to="/about">About</Link> </nav> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> </Routes> </> ); } test('renders Home component on default route', () => { render( <MemoryRouter initialEntries={["/"]}> <App /> </MemoryRouter> ); expect(screen.getByText('Home Page')).toBeInTheDocument(); }); test('renders About component on /about route', () => { render( <MemoryRouter initialEntries={["/about"]}> <App /> </MemoryRouter> ); expect(screen.getByText('About Page')).toBeInTheDocument(); });
Output
PASS renders Home component on default route
PASS renders About component on /about route
Common Pitfalls
- Not wrapping components with
MemoryRoutercauses errors because routing context is missing. - Using
BrowserRouterin tests can cause issues since it depends on browser history. - Forgetting to set
initialEntriesmeans the default route is always used, so tests may not cover other paths. - Trying to test navigation by clicking
<Link>without user-event or fireEvent can fail.
javascript
/* Wrong: Missing MemoryRouter wrapper */ import { render } from '@testing-library/react'; import App from './App'; test('fails without router', () => { expect(() => render(<App />)).toThrow(); }); /* Right: Wrap with MemoryRouter and set initialEntries */ import { MemoryRouter } from 'react-router-dom'; import { render } from '@testing-library/react'; import App from './App'; test('works with MemoryRouter', () => { render( <MemoryRouter initialEntries={["/"]}> <App /> </MemoryRouter> ); });
Quick Reference
Summary tips for testing React Router:
- Always wrap tested components with
MemoryRouter. - Use
initialEntriesto set the route you want to test. - Use
screenfrom React Testing Library to query rendered elements. - Simulate navigation with user-event or fireEvent if needed.
- Check for route-specific content to confirm correct rendering.
Key Takeaways
Wrap components with MemoryRouter and set initialEntries to test routes.
Use React Testing Library's render and screen to check rendered output.
Avoid using BrowserRouter in tests; it depends on browser history.
Simulate navigation events with user-event or fireEvent for interaction tests.
Check for route-specific content to verify correct routing behavior.