Enzyme является популярной библиотекой для тестирования компонентов
React. Одной из основных задач при тестировании является проверка
компонентов, которые зависят от контекста маршрутизации. В таких случаях
важно обеспечить корректную работу маршрутизации в тестах, и именно для
этого используется обёртывание компонентов в BrowserRouter
или другие контейнеры маршрутизации.
Когда приложение React использует маршрутизацию с помощью библиотеки
React Router, каждый компонент может иметь доступ к контексту
маршрутизации через хук useHistory,
useLocation или через компоненты типа Route.
Тестирование таких компонентов без маршрутизации приведёт к ошибкам,
поскольку эти хуки и компоненты будут ожидать наличие контекста
маршрутизации.
В связи с этим, для корректного тестирования таких компонентов
необходимо обёртывать их в компонент маршрутизации, такой как
BrowserRouter. Это обеспечит контекст маршрутов и позволит
тестировать логику, связанную с навигацией.
BrowserRouter?Для использования BrowserRouter в тестах с Enzyme, нужно
просто обернуть тестируемый компонент в BrowserRouter в
момент его рендеринга. В Enzyme это можно сделать с помощью метода
shallow или mount, в зависимости от того, как
глубоко нужно тестировать компонент.
Пример обёртывания с использованием mount:
import { mount } from 'enzyme';
import { BrowserRouter } from 'react-router-dom';
import MyComponent from './MyComponent';
describe('MyComponent', () => {
it('должен правильно рендериться внутри BrowserRouter', () => {
const wrapper = mount(
<BrowserRouter>
<MyComponent />
</BrowserRouter>
);
expect(wrapper.find(MyComponent).length).toBe(1);
});
});
В данном примере компонент MyComponent будет обёрнут в
BrowserRouter для того, чтобы иметь доступ к контексту
маршрутизации. Использование mount здесь позволяет
рендерить компонент с полным жизненным циклом, что необходимо для работы
с маршрутами.
shallow с BrowserRouterМетод shallow используется для поверхностного рендеринга
компонента, при этом дочерние компоненты не рендерятся в полном объёме.
Для того чтобы протестировать компонент с маршрутизацией в этом случае,
можно использовать shallow вместе с обёртыванием в
BrowserRouter.
import { shallow } from 'enzyme';
import { BrowserRouter } from 'react-router-dom';
import MyComponent from './MyComponent';
describe('MyComponent', () => {
it('должен правильно рендериться в shallow', () => {
const wrapper = shallow(
<BrowserRouter>
<MyComponent />
</BrowserRouter>
);
expect(wrapper.find(MyComponent).length).toBe(1);
});
});
Такой подход подходит, если вам нужно только проверить рендеринг компонента, но без углублённого тестирования его дочерних элементов.
Использование MemoryRouter вместо
BrowserRouter В некоторых случаях вместо
BrowserRouter может быть полезен компонент
MemoryRouter, который не зависит от реального URL-адреса.
Это может быть удобно, если вам нужно настроить маршрутизацию на основе
искусственного состояния, не меняя URL в браузере.
Пример:
import { mount } from 'enzyme';
import { MemoryRouter } from 'react-router-dom';
import MyComponent from './MyComponent';
describe('MyComponent', () => {
it('должен работать с MemoryRouter', () => {
const wrapper = mount(
<MemoryRouter initialEntries={['/test']}>
<MyComponent />
</MemoryRouter>
);
expect(wrapper.find(MyComponent).length).toBe(1);
});
});
В этом примере initialEntries позволяет задать начальный
маршрут, что полезно для тестов, где нужно проверить поведение
компонентов на основе определённых маршрутов.
Тестирование компонентов с Route и
Link Если компонент использует такие элементы, как
Route или Link, то важно тестировать их
взаимодействие с другими частями приложения. Например, можно проверить,
правильно ли работает переход по маршруту, и вызывает ли
Link нужный переход.
Пример тестирования Link:
import { mount } from 'enzyme';
import { BrowserRouter, Link } from 'react-router-dom';
describe('Тестирование Link', () => {
it('должен корректно переходить по маршруту', () => {
const wrapper = mount(
<BrowserRouter>
<Link to="/home">Home</Link>
</BrowserRouter>
);
expect(wrapper.find(Link).props().to).toBe('/home');
});
});Проверка работы хуков маршрутизации Если
компонент использует хук useHistory,
useLocation или другие хуки маршрутизации, то необходимо
проверять их работу в контексте BrowserRouter. Это
позволяет убедиться, что ваш компонент правильно использует информацию о
текущем маршруте и выполняет необходимые действия при изменении
маршрута.
Пример тестирования хука useHistory:
import { mount } from 'enzyme';
import { BrowserRouter, useHistory } from 'react-router-dom';
const MyComponent = () => {
const history = useHistory();
const navigate = () => {
history.push('/new-route');
};
return (
<button onCl ick={navigate}>Go</button>
);
};
describe('MyComponent', () => {
it('должен вызывать history.push при клике', () => {
const wrapper = mount(
<BrowserRouter>
<MyComponent />
</BrowserRouter>
);
wrapper.find('button').simulate('click');
// Проверка вызова push или изменения состояния маршрута
});
});Тестирование с серверным рендерингом (SSR): В
случае использования серверного рендеринга для React-приложений,
возможно, потребуется использовать другие типы маршрутизаторов, такие
как StaticRouter, вместо BrowserRouter, так
как последний зависит от работы с реальным браузером и
URL-адресом.
Тестирование с динамическими маршрутами: В
случае использования динамических маршрутов, например, с параметрами в
URL (/user/:id), важно учесть правильное переданное
состояние в MemoryRouter или BrowserRouter,
чтобы тесты проходили корректно при различных вариантах
маршрутов.
Тестирование компонентов, использующих маршрутизацию в React, требует
использования соответствующего контейнера маршрутизации, такого как
BrowserRouter. В Enzyme для этого достаточно обёрнуть
компоненты в нужный маршрутизатор при рендеринге, используя
mount или shallow. В зависимости от ситуации,
можно использовать как BrowserRouter, так и
MemoryRouter для тестов с искусственным состоянием
маршрутов.