В веб-приложениях на React часто требуется тестировать компоненты,
поведение которых зависит от параметров URL. Эти параметры могут быть
частью строки запроса (query parameters) или динамических
сегментов маршрута (route params). React Testing Library
предоставляет инструменты для рендеринга компонентов в тестовой среде,
но для работы с URL нужно учитывать интеграцию с роутером, чаще всего
react-router.
1.1 Query parameters Строка запроса — часть URL
после знака ?. Например, в URL:
/products?category=books&page=2
параметры:
category = bookspage = 21.2 Route parameters Динамические сегменты маршрута
указываются с помощью : в настройках роутера. Например:
} />
Для URL /products/42 параметр id будет
равен "42".
Для извлечения параметров URL компоненты должны быть обернуты в
роутер. В тестах обычно используется MemoryRouter:
import { render, screen } from '@testing-library/react';
import { MemoryRouter, Route, Routes } from 'react-router-dom';
import ProductDetail from './ProductDetail';
render(
} />
);
MemoryRouter позволяет задавать начальные URL с помощью
initialEntries.Routes и Route обеспечивают работу
динамических сегментов.React Router предоставляет хук useParams() для доступа к
динамическим сегментам:
import { useParams } from 'react-router-dom';
function ProductDetail() {
const { id } = useParams();
return Product ID: {id};
}
В тесте проверка выглядит так:
expect(screen.getByText('Product ID: 42')).toBeInTheDocument();
Важно: при тестировании route parameters initialEntries
должен соответствовать шаблону маршрута.
Для работы со строкой запроса используется
useLocation:
import { useLocation } from 'react-router-dom';
function ProductList() {
const { search } = useLocation();
const queryParams = new URLSearchParams(search);
const category = queryParams.get('category');
const page = queryParams.get('page');
return (
Category: {category}, Page: {page}
);
}
В тестах:
render(
);
expect(screen.getByText('Category: books, Page: 2')).toBeInTheDocument();
URLSearchParams позволяет безопасно извлекать параметры,
даже если их несколько или они отсутствуют.
Компоненты могут использовать одновременно динамические сегменты и query parameters:
function ProductPage() {
const { id } = useParams();
const queryParams = new URLSearchParams(useLocation().search);
const ref = queryParams.get('ref');
return Product {id}, Referrer: {ref};
}
Тестирование:
render(
} />
);
expect(screen.getByText('Product 42, Referrer: homepage')).toBeInTheDocument();
Для тестов, где важна конкретная строка запроса или маршрут, используются следующие подходы:
initialEntries —
имитация любой страницы.window.location через
jest.spyOn для глобальных эффектов (редко, когда компонент
не использует роутер).useParams и useLocation для изоляции
теста.Пример подмены useParams:
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useParams: () => ({ id: '99' }),
}));
Некоторые компоненты изменяют URL через useNavigate.
Проверка выполняется с помощью MemoryRouter и истории:
import { fireEvent } from '@testing-library/react';
import { useNavigate } from 'react-router-dom';
function GoToNext({ id }) {
const navigate = useNavigate();
return ;
}
Тест:
const { container } = render(
} />
);
fireEvent.click(container.querySelector('button'));
expect(container.innerHTML).toContain('Next'); // проверка перехода в более сложных случаях через location.pathname
initialEntries,
чтобы компонент видел правильный URL.screen.getByText или
screen.getByRole для проверки вывода параметров.URLSearchParams, чтобы избежать ошибок при
декодировании.initialEntries и маршрутов Route.