Снапшот-тестирование маршрутов позволяет проверять корректность отображения компонентов, связанных с конкретными путями в приложении, без необходимости вручную переходить по маршрутам в браузере. В сочетании с React Testing Library и Jest оно обеспечивает надёжный способ контроля за визуальным и функциональным состоянием маршрутов.
Для начала необходимо установить зависимости:
npm install --save-dev @testing-library/react @testing-library/jest-dom jest
npm install react-router-dom
Импортируются основные утилиты:
import { render, screen } from '@testing-library/react';
import { MemoryRouter, Route, Routes } from 'react-router-dom';
Использование MemoryRouter вместо обычного BrowserRouter позволяет создавать виртуальную историю маршрутов, что идеально подходит для тестов.
Предположим, есть структура маршрутов:
function Home() {
return <h1>Главная страница</h1>;
}
function About() {
return <h1>О приложении</h1>;
}
function App() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
);
}
Для тестирования важен корректный рендер компонента в зависимости от переданного пути.
import renderer from 'react-test-renderer';
test('рендерит главную страницу корректно', () => {
const tree = renderer
.create(
<MemoryRouter initialEntries={['/']}>
<App />
</MemoryRouter>
)
.toJSON();
expect(tree).toMatchSnapshot();
});
Пояснения:
initialEntries задаёт текущий путь в памяти.toJSON() преобразует компонент в структуру, удобную для
снапшота.toMatchSnapshot() сохраняет снимок дерева компонентов и
сравнивает его при последующих запусках теста.React Router позволяет использовать динамические сегменты URL,
например /user/:id. Для тестирования:
function User({ id }) {
return <h1>Пользователь {id}</h1>;
}
function App() {
return (
<Routes>
<Route path="/user/:id" element={<UserWrapper />} />
</Routes>
);
}
function UserWrapper() {
const { id } = useParams();
return <User id={id} />;
}
Снапшот-тест:
test('рендерит страницу пользователя', () => {
const tree = renderer
.create(
<MemoryRouter initialEntries={['/user/42']}>
<App />
</MemoryRouter>
)
.toJSON();
expect(tree).toMatchSnapshot();
});
Использование useParams() позволяет динамически получать
параметры маршрута, а initialEntries имитирует путь с
конкретным значением.
Для проверки переходов можно использовать компонент Link
и библиотеку user-event:
import { Link } from 'react-router-dom';
import userEvent from '@testing-library/user-event';
function Nav() {
return (
<>
<Link to="/">Главная</Link>
<Link to="/about">О приложении</Link>
</>
);
}
test('переход по ссылкам корректен', async () => {
render(
<MemoryRouter initialEntries={['/']}>
<Nav />
<App />
</MemoryRouter>
);
await userEvent.click(screen.getByText('О приложении'));
expect(screen.getByText('О приложении')).toBeInTheDocument();
});
В данном случае проверяется не только визуальный вид, но и функциональность перехода между маршрутами.
Вложенные маршруты часто используют Outlet:
function Dashboard() {
return (
<div>
<h1>Панель управления</h1>
<Outlet />
</div>
);
}
function Stats() {
return <h2>Статистика</h2>;
}
function App() {
return (
<Routes>
<Route path="/dashboard" element={<Dashboard />}>
<Route path="stats" element={<Stats />} />
</Route>
</Routes>
);
}
Тестирование вложенного маршрута:
test('рендер вложенного маршрута', () => {
const tree = renderer
.create(
<MemoryRouter initialEntries={['/dashboard/stats']}>
<App />
</MemoryRouter>
)
.toJSON();
expect(tree).toMatchSnapshot();
});
В этом случае снапшот включает сразу родительский и дочерний компоненты, что позволяет контролировать корректность рендеринга вложенной структуры.
screen.getByText
или screen.getByRole.Снапшот-тестирование маршрутов позволяет создавать надёжные, повторяемые тесты для приложений на React с использованием React Router, гарантируя, что при изменениях структуры или содержимого маршрутов визуальное отображение компонентов остаётся ожидаемым.