How to Test React Router Link Component
Testing the Link component in React, typically provided
by libraries like React Router, ensures that application navigation
functions correctly and links point to the correct destinations. This
guide demonstrates how to test a React Link component using
Jest and React Testing Library. You will learn how to wrap your
component in a routing context, simulate user clicks, and verify that
navigation occurs successfully.
The Challenge with Testing Link Components
The React Router Link component cannot be rendered in
isolation during a test. If you attempt to render it without a router
context, React Router will throw an error:
useHref() may be used only in the context of a <Router> component.
To solve this, you must wrap the component under test inside a router
provider designed for testing, such as MemoryRouter.
Step-by-Step Testing Guide
1. The Component under Test
Consider a simple navigation component that contains a
Link pointing to an “About” page:
// Navigation.jsx
import { Link } from 'react-router-dom';
export default function Navigation() {
return (
<nav>
<Link to="/about">About Us</Link>
</nav>
);
}2. Set Up the Test with MemoryRouter
MemoryRouter is a router implementation that stores its
location history in memory. This makes it ideal for testing environments
like Jest/JSDOM where there is no real browser address bar.
Here is how to write the test to verify that the link rendered
correctly and has the proper href attribute:
// Navigation.test.jsx
import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import Navigation from './Navigation';
describe('Navigation Component', () => {
test('renders the link with the correct href', () => {
render(
<MemoryRouter>
<Navigation />
</MemoryRouter>
);
const linkElement = screen.getByRole('link', { name: /about us/i });
expect(linkElement).toBeInTheDocument();
expect(linkElement).toHaveAttribute('href', '/about');
});
});3. Testing Navigation Behavior (Simulating Clicks)
To verify that clicking the link actually navigates the user to the
correct page, you can set up routes inside your test wrapper using
Routes and Route.
Use @testing-library/user-event to simulate the user
click realistically.
// Navigation.test.jsx
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MemoryRouter, Routes, Route } from 'react-router-dom';
import Navigation from './Navigation';
describe('Navigation Click Behavior', () => {
test('navigates to the about page on link click', async () => {
render(
<MemoryRouter initialEntries={['/']}>
<Routes>
<Route path="/" element={<Navigation />} />
<Route path="/about" element={<div>About Page Content</div>} />
</Routes>
</MemoryRouter>
);
const linkElement = screen.getByRole('link', { name: /about us/i });
// Simulate clicking the link
await userEvent.click(linkElement);
// Verify the UI updated to show the new route's content
expect(screen.getByText('About Page Content')).toBeInTheDocument();
});
});Summary of Best Practices
- Use MemoryRouter: Always wrap your components in
MemoryRouterto provide the necessary routing context without relying on a browser environment. - Assert on Attributes: Use
toHaveAttribute('href', '/destination')to quickly check if the link points to the correct location. - Test the Outcome: For critical user flows, render
target routes within
Routesand useuserEvent.click()to confirm that clicking the link renders the expected page content.