Loader-функции в TanStack Router отвечают за асинхронную загрузку данных перед рендерингом маршрута. Тестирование этих функций позволяет гарантировать корректность работы маршрутизатора, предотвращает ошибки при асинхронной логике и упрощает поддержку приложения.
Loader-функция — это асинхронная функция, принимающая объект с параметрами маршрута, и возвращающая данные, которые будут переданы компоненту маршрута:
async function loader({ params, request }) {
const response = await fetch(`/api/items/${params.id}`);
if (!response.ok) throw new Error('Failed to fetch item');
return response.json();
}
Ключевые моменты для тестирования:
params и
request).Для тестирования loader-функций важно изолировать их от реальных сетевых запросов или других побочных эффектов. Наиболее распространённые подходы:
fetch:global.fetch = jest.fn();
beforeEach(() => {
fetch.mockClear();
});
test('loader возвращает данные', async () => {
fetch.mockResolvedValueOnce({
ok: true,
json: async () => ({ id: 1, name: 'Item 1' })
});
const data = await loader({ params: { id: '1' } });
expect(data).toEqual({ id: 1, name: 'Item 1' });
});
jest.mock:Если данные загружаются через отдельный модуль API:
import * as api from './api';
jest.mock('./api');
api.getItem.mockResolvedValue({ id: 1, name: 'Item 1' });
test('loader вызывает API и возвращает данные', async () => {
const data = await loader({ params: { id: '1' } });
expect(api.getItem).toHaveBeenCalledWith('1');
expect(data).toEqual({ id: 1, name: 'Item 1' });
});
Loader должен корректно обрабатывать ошибки, например при сетевых сбоях или некорректных данных. Тесты для таких случаев обеспечивают стабильность маршрутов:
test('loader выбрасывает ошибку при неуспешном fetch', async () => {
fetch.mockResolvedValueOnce({ ok: false });
await expect(loader({ params: { id: '1' } })).rejects.toThrow('Failed to fetch item');
});
Также важно тестировать сценарии с отсутствующими параметрами:
test('loader выбрасывает ошибку при отсутствии параметра id', async () => {
await expect(loader({ params: {} })).rejects.toThrow();
});
Loader-функции тесно связаны с маршрутизатором. Для комплексной
проверки можно использовать render маршрута в тестовой
среде:
import { createMemoryRouter, RouterProvider } from '@tanstack/router';
import { render, screen, waitFor } from '@testing-library/react';
import routes from './routes';
test('маршрут корректно загружает данные через loader', async () => {
const router = createMemoryRouter(routes, { initialEntries: ['/items/1'] });
render(<RouterProvider router={router} />);
await waitFor(() => screen.getByText('Item 1'));
expect(screen.getByText('Item 1')).toBeInTheDocument();
});
Такой подход проверяет не только loader, но и интеграцию с компонентами маршрута, рендеринг данных и обработку асинхронной логики.
async/await и waitFor для
тестирования асинхронного поведения.Тщательное тестирование loader-функций повышает стабильность приложения и упрощает сопровождение сложных маршрутов с динамической загрузкой данных.