TanStack Router предоставляет мощный и гибкий инструмент для организации маршрутизации в приложениях на JavaScript и TypeScript. Интеграционное тестирование навигации позволяет убедиться, что переходы между маршрутами, обработка параметров и асинхронная подгрузка данных работают корректно во всех сценариях.
Для интеграционного тестирования навигации необходимо использовать библиотеку для рендеринга компонентов в тестах, например, @testing-library/react, и утилиты для работы с асинхронным поведением, такие как @testing-library/jest-dom и jest. Основная цель – имитировать поведение пользователя и проверять состояние приложения после навигации.
Пример базовой настройки:
import { render, screen } from '@testing-library/react';
import { RouterProvider, createRouter, Route } from '@tanstack/router';
import App from './App';
const router = createRouter({
routes: [
new Route({ path: '/', component: Home }),
new Route({ path: '/about', component: About }),
new Route({ path: '/profile/:id', component: Profile }),
],
});
function renderWithRouter(ui, { route = '/' } = {}) {
window.history.pushState({}, 'Test page', route);
return render(<RouterProvider router={router}>{ui}</RouterProvider>);
}
В данном примере создается тестовый роутер с базовыми маршрутами, а
вспомогательная функция renderWithRouter позволяет
рендерить компоненты в контексте маршрутизатора и задавать стартовый
путь.
Для проверки навигации необходимо эмулировать действия пользователя:
клики по ссылкам, программные переходы через
router.navigate, а затем проверять, что отображается
корректный компонент.
import userEvent from '@testing-library/user-event';
test('переход на страницу About', async () => {
renderWithRouter(<App />);
const aboutLink = screen.getByText('About');
await userEvent.click(aboutLink);
expect(screen.getByText('Страница About')).toBeInTheDocument();
});
Ключевой момент: проверка должна быть основана на визуальных или текстовых признаках контента, а не на внутреннем состоянии роутера. Это обеспечивает высокую устойчивость тестов к изменениям внутренней реализации.
TanStack Router поддерживает динамические сегменты, например
/profile/:id. Для интеграционного тестирования важно
проверять корректность передачи параметров и рендеринг соответствующего
контента.
test('отображение профиля пользователя с id', async () => {
renderWithRouter(<App />, { route: '/profile/42' });
expect(screen.getByText('Профиль пользователя 42')).toBeInTheDocument();
});
В этом примере проверяется, что маршрут с параметром id
корректно подставляется в компонент и отображается ожидаемый текст. Для
более сложных сценариев можно использовать мокированные запросы к API и
проверять их вызовы.
Маршруты часто используют loader или
loaderData для асинхронного получения данных. В тестах
важно мокировать сетевые запросы и проверять, что данные отображаются
после завершения загрузки.
import { rest } from 'msw';
import { setupServer } from 'msw/node';
const server = setupServer(
rest.get('/api/profile/42', (req, res, ctx) => {
return res(ctx.json({ name: 'Иван' }));
})
);
beforeAll(() => server.listen());
afterAll(() => server.close());
afterEach(() => server.resetHandlers());
test('загрузка данных профиля через loader', async () => {
renderWithRouter(<App />, { route: '/profile/42' });
expect(await screen.findByText('Иван')).toBeInTheDocument();
});
findByText используется для ожидания асинхронного
рендеринга. Такой подход позволяет интеграционно протестировать полный
цикл: навигацию → загрузку данных → отображение контента.
TanStack Router поддерживает вложенные маршруты, что требует проверки корректного рендеринга дочерних компонентов. В тестах важно эмулировать переход к родительскому маршруту с вложенными дочерними маршрутами и проверять отображение всех уровней.
test('вложенные маршруты работают корректно', async () => {
renderWithRouter(<App />, { route: '/dashboard/settings' });
expect(screen.getByText('Панель управления')).toBeInTheDocument();
expect(screen.getByText('Настройки')).toBeInTheDocument();
});
Необходимо проверять сценарии, когда пользователь переходит на
несуществующий маршрут или возникает ошибка в loader.
TanStack Router позволяет использовать errorComponent или
notFoundComponent.
test('неизвестный маршрут отображает 404', async () => {
renderWithRouter(<App />, { route: '/unknown-route' });
expect(screen.getByText('Страница не найдена')).toBeInTheDocument();
});
Такое тестирование гарантирует, что пользовательский опыт останется стабильным даже при ошибках навигации.
Интеграционные тесты навигации в TanStack Router помогают убедиться в надежности маршрутизации, правильной подгрузке данных и корректной работе сложных сценариев с динамическими и вложенными маршрутами.