How to Test React Router Outlet Component
Testing the <Outlet /> component in React Router
is essential for ensuring that nested routes render their child
components correctly. This article provides a straightforward,
step-by-step guide on how to test React Router’s Outlet
component using React Testing Library and Jest, covering both
integration testing with MemoryRouter and mock-based unit
testing.
Method 1: Integration Testing with MemoryRouter (Recommended)
The most reliable way to test a component containing an
<Outlet /> is through an integration test. By using
MemoryRouter (or createMemoryRouter), you can
simulate actual routing behavior and verify that the correct child
components render inside the parent layout.
The Component to Test
Consider a layout component that uses Outlet to render
nested child components:
// DashboardLayout.jsx
import { Outlet, Link } from 'react-router-dom';
export default function DashboardLayout() {
return (
<div>
<nav>
<Link to="/dashboard/profile">Profile</Link>
</nav>
<header>
<h1>Dashboard Header</h1>
</header>
<main>
<Outlet />
</main>
</div>
);
}The Test File
Use createMemoryRouter to define a mock routing tree.
This allows you to test what renders inside the Outlet when
navigating to specific paths.
// DashboardLayout.test.jsx
import { render, screen } from '@testing-library/react';
import { RouterProvider, createMemoryRouter } from 'react-router-dom';
import DashboardLayout from './DashboardLayout';
describe('DashboardLayout Component', () => {
test('renders the layout and the nested outlet route component', () => {
const routes = [
{
path: '/dashboard',
element: <DashboardLayout />,
children: [
{
path: 'profile',
element: <div>Profile Page Content</div>,
},
],
},
];
// Start the router at the specific child path
const router = createMemoryRouter(routes, {
initialEntries: ['/dashboard/profile'],
});
render(<RouterProvider router={router} />);
// Assert that the layout elements are rendered
expect(screen.getByText('Dashboard Header')).toBeInTheDocument();
// Assert that the child component inside the Outlet is rendered
expect(screen.getByText('Profile Page Content')).toBeInTheDocument();
});
});Method 2: Mocking the Outlet Component (Isolated Unit Test)
If you only want to verify that the parent layout contains the
Outlet component without testing the routing logic, you can
mock react-router-dom using Jest.
The Test File
In this approach, you replace the real Outlet with a
placeholder test ID to confirm its presence in the DOM.
// DashboardLayout.isolated.test.jsx
import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import DashboardLayout from './DashboardLayout';
// Mock react-router-dom to stub out the Outlet component
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
Outlet: () => <div data-testid="mock-outlet" />,
}));
describe('DashboardLayout Isolated Unit Test', () => {
test('renders the layout and contains the Outlet component placeholder', () => {
render(
<MemoryRouter>
<DashboardLayout />
</MemoryRouter>
);
// Verify layout header is present
expect(screen.getByText('Dashboard Header')).toBeInTheDocument();
// Verify the mocked Outlet is rendered inside the layout
expect(screen.getByTestId('mock-outlet')).toBeInTheDocument();
});
});