MemoryRouter — это специальный тип роутера из
библиотеки react-router-dom, который используется
преимущественно в тестах и в сценариях, где не требуется работа с
настоящим URL браузера. В отличие от BrowserRouter, который
синхронизирует состояние маршрутов с адресной строкой,
MemoryRouter хранит историю навигации в
памяти, что делает его идеальным для изолированного
тестирования компонентов с маршрутизацией.
Изолированная история MemoryRouter
не взаимодействует с реальным браузером, поэтому все изменения пути
существуют только в тестовой среде. Это обеспечивает предсказуемость
тестов, особенно при проверке редиректов, переходов между страницами и
состояния компонентов, зависящего от маршрута.
Начальные маршруты Через проп
initialEntries можно задать массив путей, которые будут
использоваться в качестве стартовой истории навигации.
<MemoryRouter initialEntries={['/login']}>
<App />
</MemoryRouter>
В этом примере компонент App будет рендериться так, как
если бы пользователь сразу перешёл на /login.
Начальный индекс Проп initialIndex
позволяет указать, какой путь из initialEntries
использовать как текущий.
<MemoryRouter initialEntries={['/home', '/profile']} initialIndex={1}>
<App />
</MemoryRouter>
Здесь текущий путь будет /profile, хотя
/home находится в истории.
Контроль истории Объект истории можно получить
через useNavigate или useLocation внутри
компонента, что позволяет тестировать навигацию программно.
Например:
import { render, screen } from '@testing-library/react';
import { MemoryRouter, Routes, Route, useNavigate } from 'react-router-dom';
function Login() {
const navigate = useNavigate();
return <button onCl ick={() => navigate('/dashboard')}>Войти</button>;
}
test('переход на dashboard после клика', () => {
render(
<MemoryRouter initialEntries={['/login']}>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/dashboard" element={<div>Dashboard</div>} />
</Routes>
</MemoryRouter>
);
screen.getByText('Войти').click();
expect(screen.getByText('Dashboard')).toBeInTheDocument();
});initialEntries позволяет задавать стартовый маршрут и
проверять, корректно ли компонент выполняет перенаправление.MemoryRouter поддерживает любую вложенность маршрутов через
компонент Routes. Это удобно при проверке сложной структуры
приложения.useLocation и useNavigationType можно
тестировать, какой маршрут был посещён, и какие действия навигации
выполнялись (PUSH, REPLACE,
POP).Синхронизация с React Testing Library
MemoryRouter идеально сочетается с render из
@testing-library/react, так как оба инструмента
предназначены для изолированного тестирования компонентов.
События навигации Поскольку навигация полностью
контролируется памятью, нельзя тестировать эффекты, связанные с
изменением адресной строки в браузере (например, событие
popstate). Все такие сценарии нужно эмулировать вручную
через initialEntries или программное управление
историей.
Комбинация с пользовательскими хуками
Компоненты, использующие useNavigate,
useParams или useLocation, корректно работают
внутри MemoryRouter, что позволяет полностью эмулировать
поведение роутинга без запуска браузера.
1. Тест редиректа после авторизации
function AuthRoute({ isAuthenticated, children }) {
return isAuthenticated ? children : <Navigate to="/login" />;
}
test('редирект на login при неавторизованном доступе', () => {
render(
<MemoryRouter initialEntries={['/dashboard']}>
<Routes>
<Route path="/dashboard" element={<AuthRoute isAuthenticated={false}><div>Dashboard</div></AuthRoute>} />
<Route path="/login" element={<div>Login</div>} />
</Routes>
</MemoryRouter>
);
expect(screen.getByText('Login')).toBeInTheDocument();
});
2. Тест навигации между страницами
function Navbar() {
const navigate = useNavigate();
return (
<>
<button onCl ick={() => navigate('/')}>Главная</button>
<button onCl ick={() => navigate('/about')}>О нас</button>
</>
);
}
test('переход на страницу О нас', () => {
render(
<MemoryRouter initialEntries={['/']}>
<Routes>
<Route path="/" element={<Navbar />} />
<Route path="/about" element={<div>About Page</div>} />
</Routes>
</MemoryRouter>
);
screen.getByText('О нас').click();
expect(screen.getByText('About Page')).toBeInTheDocument();
});
MemoryRouter обеспечивает предсказуемую и контролируемую
среду для тестирования компонентов с маршрутизацией. Его ключевые
преимущества — отсутствие зависимости от браузера, возможность задавать
начальные маршруты и удобная интеграция с React Testing Library.