В процессе тестирования JavaScript-приложений важно учитывать поведение перенаправлений, особенно когда приложение взаимодействует с сервером или изменяет маршруты на клиентской стороне. Enzyme, хотя и не предоставляет прямой функции для тестирования перенаправлений, может быть использован для проверки компонентов, которые инициируют или обрабатывают такие действия.
Если приложение использует библиотеку 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, который хранит
информацию о текущем маршруте и позволяет изменять его программно. Для
этого можно воспользоваться библиотекой 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 и использования различных подходов можно эффективно тестировать компоненты, которые зависят от изменения маршрута.