В современном веб-разработке часто используются маршрутизаторы, такие
как react-router, для навигации по приложениям. В этом
контексте компоненты Link и NavLink играют
ключевую роль в управлении переходами между различными страницами.
Тестирование этих компонентов с использованием Enzyme важно для
обеспечения корректной работы навигации в приложении.
LinkКомпонент Link из react-router-dom
позволяет пользователям переходить на другие страницы приложения без
полной перезагрузки страницы. Он обрабатывает навигацию, предотвращая
стандартное поведение ссылок HTML, и использует историю браузера для
манипулирования состоянием маршрутов. В Enzyme тестирование этого
компонента важно для проверки того, что ссылка отрабатывает
корректно.
LinkПроверка рендеринга компонента
Простой тест, который проверяет, что компонент Link
рендерится без ошибок и имеет нужные атрибуты:
import { shallow } from 'enzyme';
import { Link } from 'react-router-dom';
test('Компонент Link рендерится корректно', () => {
const wrapper = shallow(<Link to="/home">Home</Link>);
expect(wrapper.exists()).toBe(true);
expect(wrapper.prop('to')).toBe('/home');
});Проверка кликабельности
Для проверки функциональности ссылки важно убедиться, что клик по компоненту вызывает нужное поведение. Для этого можно использовать Enzyme вместе с моками и проверками:
import { mount } from 'enzyme';
import { Link } from 'react-router-dom';
import { MemoryRouter } from 'react-router-dom';
test('Клик по компоненту Link приводит к изменению маршрута', () => {
const wrapper = mount(
<MemoryRouter initialEntries={['/']}>
<Link to="/home">Home</Link>
</MemoryRouter>
);
wrapper.find('a').simulate('click', { button: 0 });
expect(wrapper.find(Link).prop('to')).toBe('/home');
});NavLinkNavLink из react-router-dom является
расширением компонента Link, предоставляя дополнительные
функции для стилизации активных ссылок. Он имеет пропс
activeClassName, который позволяет применить класс CSS к
ссылке, когда она активна, а также isActive, который
позволяет вручную определить, является ли ссылка активной.
NavLinkПроверка активного класса
Один из важных аспектов тестирования NavLink — это
проверка, что активный маршрут правильно выделяется, например, путем
применения CSS класса. Для этого можно проверить наличие активного
класса в зависимости от маршрута.
import { mount } from 'enzyme';
import { NavLink } from 'react-router-dom';
import { MemoryRouter } from 'react-router-dom';
test('NavLink применяет активный класс', () => {
const wrapper = mount(
<MemoryRouter initialEntries={['/home']}>
<NavLink to="/home" activeClassName="active">
Home
</NavLink>
<NavLink to="/about" activeClassName="active">
About
</NavLink>
</MemoryRouter>
);
expect(wrapper.find(NavLink).at(0).hasClass('active')).toBe(true);
expect(wrapper.find(NavLink).at(1).hasClass('active')).toBe(false);
});Проверка активного состояния через
isActive
Пропс isActive позволяет вручную задавать, активна ли
ссылка. Это может быть полезно для более сложных логик отображения
активных ссылок, например, в случае динамически меняющихся
маршрутов.
import { mount } from 'enzyme';
import { NavLink } from 'react-router-dom';
import { MemoryRouter } from 'react-router-dom';
test('NavLink с пропсом isActive работает корректно', () => {
const wrapper = mount(
<MemoryRouter initialEntries={['/home']}>
<NavLink
to="/home"
isActive={(match, location) => location.pathname === '/home'}
activeClassName="active"
>
Home
</NavLink>
</MemoryRouter>
);
expect(wrapper.find(NavLink).hasClass('active')).toBe(true);
});Проверка с несколькими NavLink
В реальных приложениях часто бывает несколько активных ссылок. Например, в навигационном меню несколько элементов могут указывать на один и тот же маршрут. Важно протестировать такие случаи, чтобы убедиться, что только одна ссылка активна.
import { mount } from 'enzyme';
import { NavLink } from 'react-router-dom';
import { MemoryRouter } from 'react-router-dom';
test('Только одна ссылка активна из нескольких', () => {
const wrapper = mount(
<MemoryRouter initialEntries={['/home']}>
<NavLink to="/home" activeClassName="active">Home</NavLink>
<NavLink to="/about" activeClassName="active">About</NavLink>
</MemoryRouter>
);
const activeLinks = wrapper.find('.active');
expect(activeLinks.length).toBe(1);
expect(activeLinks.text()).toBe('Home');
});В некоторых случаях компоненты Link и
NavLink используют контекст маршрута, который
предоставляется с помощью компонента BrowserRouter или
MemoryRouter. Для тестирования этих компонентов важно
использовать соответствующий контейнер маршрута, чтобы убедиться, что
компоненты правильно обрабатывают состояние маршрутов.
import { mount } from 'enzyme';
import { Link } from 'react-router-dom';
import { MemoryRouter } from 'react-router-dom';
test('Link работает в контексте MemoryRouter', () => {
const wrapper = mount(
<MemoryRouter initialEntries={['/']}>
<Link to="/home">Home</Link>
</MemoryRouter>
);
wrapper.find('a').simulate('click', { button: 0 });
expect(wrapper.find(Link).prop('to')).toBe('/home');
});
Компоненты Link и NavLink могут быть
вложены в другие компоненты, и важно проверять, что они корректно
работают даже в более сложных структурах. Например, можно тестировать их
в составе навигационного меню с вложенными маршрутами.
import { mount } from 'enzyme';
import { NavLink, Route } from 'react-router-dom';
import { MemoryRouter } from 'react-router-dom';
test('NavLink работает с вложенными маршрутами', () => {
const wrapper = mount(
<MemoryRouter initialEntries={['/home']}>
<NavLink to="/home" activeClassName="active">Home</NavLink>
<Route path="/home" render={() => <div>Home Page</div>} />
</MemoryRouter>
);
expect(wrapper.find(NavLink).hasClass('active')).toBe(true);
expect(wrapper.find('div').text()).toBe('Home Page');
});
Тестирование компонентов Link и NavLink с
использованием Enzyme требует внимания к различным аспектам: рендеринг,
проверка маршрутов, активные классы и взаимодействие с контекстом
маршрутов. Правильное тестирование этих компонентов обеспечивает
стабильность навигации и улучшает качество приложения.