Проверка перенаправлений

В процессе тестирования JavaScript-приложений важно учитывать поведение перенаправлений, особенно когда приложение взаимодействует с сервером или изменяет маршруты на клиентской стороне. Enzyme, хотя и не предоставляет прямой функции для тестирования перенаправлений, может быть использован для проверки компонентов, которые инициируют или обрабатывают такие действия.

Проверка перенаправлений в компонентах с React Router

Если приложение использует библиотеку React Router для маршрутизации, то важно тестировать, как компоненты ведут себя при изменении маршрута. Для этого Enzyme может быть интегрирован с React Router. Задача заключается в том, чтобы симулировать переходы между маршрутами и убедиться, что компоненты корректно перерисовываются в соответствии с новыми путями.

Для начала необходимо импортировать необходимые модули для работы с React Router и Enzyme:

import { mount } from 'enzyme';
import { MemoryRouter } from 'react-router-dom';
import MyComponent from './MyComponent';  // компонент, содержащий логику перенаправления

Затем создаем тест, который будет монтировать компонент внутри MemoryRouter. Это позволяет протестировать компоненты, которые зависят от маршрутов, без необходимости развертывания полноценного приложения:

it('должен перенаправить на правильный маршрут', () => {
  const wrapper = mount(
    <MemoryRouter initialEntries={['/initial']}>
      <MyComponent />
    </MemoryRouter>
  );

  // проверяем, что компонент отрендерился на исходном пути
  expect(wrapper.find('.some-element').text()).toBe('Initial State');

  // симулируем изменение маршрута
  wrapper.find('button').simulate('click');  // допустим, кнопка вызывает редирект

  // перерисовываем компонент
  wrapper.update();

  // проверяем, что мы перенаправлены на новый маршрут
  expect(wrapper.find('.some-element').text()).toBe('Redirected State');
});

В этом примере используется MemoryRouter, который позволяет эмулировать навигацию внутри теста, не полагаясь на браузер или сервер.

Тестирование перенаправлений с использованием history API

Иногда необходимо проверить не только конечный результат (новый маршрут), но и сам процесс изменения маршрута. В таких случаях можно использовать доступ к объекту history, который хранит информацию о текущем маршруте и позволяет изменять его программно. Для этого можно воспользоваться библиотекой history, которая интегрирована в React Router.

Для тестирования компонента, который выполняет перенаправление программно, создается тест с доступом к объекту history:

import { createMemoryHistory } from 'history';
import { Router } from 'react-router-dom';

it('должен перенаправить с использованием history', () => {
  const history = createMemoryHistory();
  history.push('/initial');

  const wrapper = mount(
    <Router history={history}>
      <MyComponent />
    </Router>
  );

  // проверяем исходный маршрут
  expect(history.location.pathname).toBe('/initial');

  // симулируем действие, вызывающее редирект
  wrapper.find('button').simulate('click');

  // перерисовываем компонент
  wrapper.update();

  // проверяем новый маршрут
  expect(history.location.pathname).toBe('/new-route');
});

Здесь объект history предоставляет доступ к текущему состоянию маршрута, и тест проверяет изменение маршрута при взаимодействии с компонентом.

Проверка перенаправлений через хуки

В компонентах, использующих React Hooks, для перенаправлений может быть использован хук useHistory или useNavigate (в зависимости от версии React Router). В этом случае важно не только убедиться, что перенаправление происходит, но и проверить работу хука в тестах.

Пример компонента с использованием хука useNavigate (для React Router v6):

import { useNavigate } from 'react-router-dom';

const MyComponent = () => {
  const navigate = useNavigate();

  const handleRedirect = () => {
    navigate('/new-route');
  };

  return <button onCl ick={handleRedirect}>Go to new route</button>;
};

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

import { mount } from 'enzyme';
import { BrowserRouter } from 'react-router-dom';

it('должен перенаправить при клике на кнопку', () => {
  const wrapper = mount(
    <BrowserRouter>
      <MyComponent />
    </BrowserRouter>
  );

  // проверяем начальный маршрут
  expect(wrapper.find('button').exists()).toBe(true);

  // симулируем клик
  wrapper.find('button').simulate('click');

  // проверяем, что маршрут изменился
  expect(window.location.pathname).toBe('/new-route');
});

Здесь используется стандартный браузерный BrowserRouter, и через симуляцию клика проверяется, что маршрут изменяется.

Тестирование перенаправлений через серверные вызовы

В некоторых случаях перенаправления могут быть связаны с ответами от сервера. Например, при успешной авторизации сервер может отправить ответ, который инициирует перенаправление на другую страницу. В таких случаях необходимо мокировать вызовы API и проверять поведение компонента при изменении маршрута.

Пример теста с мокированием серверного ответа:

import { mount } from 'enzyme';
import { MemoryRouter } from 'react-router-dom';
import axios from 'axios';
import MyComponent from './MyComponent';

jest.mock('axios');

it('должен перенаправить после успешного ответа от сервера', async () => {
  axios.post.mockResolvedValueOnce({ data: { success: true } });

  const wrapper = mount(
    <MemoryRouter initialEntries={['/login']}>
      <MyComponent />
    </MemoryRouter>
  );

  // проверяем начальный маршрут
  expect(wrapper.find('.login-page').exists()).toBe(true);

  // симулируем отправку формы
  wrapper.find('form').simulate('submit');

  // ожидаем изменения состояния компонента
  await new Promise(resolve => setImmediate(resolve));
  wrapper.update();

  // проверяем новый маршрут
  expect(wrapper.find('.home-page').exists()).toBe(true);
});

В этом примере сначала мокаются HTTP-запросы с помощью jest.mock('axios'), затем после симуляции отправки формы тестируется перенаправление на новую страницу, основанное на успешном ответе сервера.

Заключение

Тестирование перенаправлений в React-приложениях с использованием Enzyme требует внимательного подхода в зависимости от того, какие именно механизмы маршрутизации используются в проекте. Важно понимать, что Enzyme не предоставляет прямых методов для проверки перенаправлений, но с помощью интеграции с React Router и использования различных подходов можно эффективно тестировать компоненты, которые зависят от изменения маршрута.