Параметры URL и их извлечение

В веб-приложениях на React часто требуется тестировать компоненты, поведение которых зависит от параметров URL. Эти параметры могут быть частью строки запроса (query parameters) или динамических сегментов маршрута (route params). React Testing Library предоставляет инструменты для рендеринга компонентов в тестовой среде, но для работы с URL нужно учитывать интеграцию с роутером, чаще всего react-router.


1. Основные типы параметров URL

1.1 Query parameters Строка запроса — часть URL после знака ?. Например, в URL:

/products?category=books&page=2

параметры:

  • category = books
  • page = 2

1.2 Route parameters Динамические сегменты маршрута указываются с помощью : в настройках роутера. Например:

} />

Для URL /products/42 параметр id будет равен "42".


2. Подготовка тестовой среды

Для извлечения параметров 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 обеспечивают работу динамических сегментов.

3. Извлечение route parameters

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 должен соответствовать шаблону маршрута.


4. Извлечение query parameters

Для работы со строкой запроса используется 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 позволяет безопасно извлекать параметры, даже если их несколько или они отсутствуют.


5. Комбинация route и query parameters

Компоненты могут использовать одновременно динамические сегменты и 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();

6. Мока URL в тестах

Для тестов, где важна конкретная строка запроса или маршрут, используются следующие подходы:

  • MemoryRouter с initialEntries — имитация любой страницы.
  • Переопределение window.location через jest.spyOn для глобальных эффектов (редко, когда компонент не использует роутер).
  • Встроенные mock функции React Router — можно подменять useParams и useLocation для изоляции теста.

Пример подмены useParams:

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useParams: () => ({ id: '99' }),
}));

7. Тестирование изменений URL

Некоторые компоненты изменяют 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

8. Практические рекомендации

  • Для стабильных тестов всегда задавать initialEntries, чтобы компонент видел правильный URL.
  • Использовать screen.getByText или screen.getByRole для проверки вывода параметров.
  • При работе с query parameters всегда использовать URLSearchParams, чтобы избежать ошибок при декодировании.
  • Для изоляции тестов можно мокать хуки роутера вместо рендеринга сложной структуры маршрутов.
  • Комбинация route и query parameters требует аккуратного соответствия initialEntries и маршрутов Route.