When testing components that use React Router for navigation, consider the following key points:
1. Wrap Components with a Router Provider
Since React Router relies on context, wrap the component in a suitable router (e.g., MemoryRouter, BrowserRouter) during testing to avoid errors like useNavigate() may be used only in the context of a <Router>.
Example:
import { MemoryRouter } from 'react-router-dom';
test('renders component with navigation', () => {
render(
<MemoryRouter>
<App />
</MemoryRouter>
);
});
2. Use MemoryRouter for Testing
MemoryRouter is ideal for tests because it keeps navigation history in memory (no browser dependency).
Manually set initial routes using the initialEntries prop.
Example:
<MemoryRouter initialEntries={['/dashboard']}>
<App />
</MemoryRouter>
3. Mock useNavigate for Programmatic Navigation
If the component uses useNavigate(), mock it to verify navigation actions.
Example with Jest:
const mockNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useNavigate: () => mockNavigate,
}));
test('navigates on button click', () => {
render(<MyComponent />);
fireEvent.click(screen.getByText('Go to Home'));
expect(mockNavigate).toHaveBeenCalledWith('/home');
});
4. Test Route Matching & Conditional Rendering
Verify that components render correctly based on the current route.
Example:
test('shows home page at /home', () => {
render(
<MemoryRouter initialEntries={['/home']}>
<Routes>
<Route path="/home" element={<HomePage />} />
</Routes>
</MemoryRouter>
);
expect(screen.getByText('Welcome Home')).toBeInTheDocument();
});