Enzyme предоставляет два основных метода для работы с компонентами
React — mount и shallow. Метод
shallow позволяет тестировать компоненты без рендеринга их
детей, что делает тесты быстрее и удобнее для изолированных проверок.
ShallowWrapper — это объект, возвращаемый при использовании
метода shallow. Он включает в себя различные утилиты для
взаимодействия с компонентами и их элементами. Однако часто возникает
необходимость расширить функциональность этого объекта, добавив
кастомные методы или улучшив уже существующие.
ShallowWrapperДо того как углубляться в расширение ShallowWrapper,
стоит отметить основные методы, предоставляемые Enzyme для работы с
ним:
find(selector) — находит элементы внутри обёрнутого
компонента с помощью CSS-селекторов.text() — извлекает текст из компонента или
элемента.simulate(event, [data]) — симулирует события (например,
click, change и т. п.).props() — возвращает свойства компонента.setProps(nextProps) — позволяет изменить пропсы
компонента и перерисовать его.Эти методы являются основой для работы с обёртками компонентов. Однако в реальных приложениях может возникнуть необходимость в добавлении новых утилит или методик для более сложных тестов.
Enzyme предоставляет несколько способов для расширения функционала
ShallowWrapper. Это можно сделать с помощью создания
собственных методов или добавления утилит для более специфичных тестов.
Обычно для этого используется концепция прототипного наследования.
Предположим, необходимо добавить метод для поиска первого элемента внутри компонента с определённым классом, но только если он существует, без ошибок в случае отсутствия элемента.
Для этого можно расширить прототип ShallowWrapper,
добавив новый метод findFirst. Этот метод будет искать
элемент и возвращать его только в том случае, если он существует, иначе
возвращать null.
import { shallow } from 'enzyme';
// Расширение прототипа ShallowWrapper
ShallowWrapper.prototype.findFirst = function(className) {
const element = this.find(className);
return element.length > 0 ? element : null;
};
// Пример использования
const wrapper = shallow(<MyComponent />);
const result = wrapper.findFirst('.some-class');
В этом примере метод findFirst будет искать первый
элемент с классом .some-class. Если такой элемент не
найден, метод вернёт null, что предотвращает возможные
ошибки при дальнейших манипуляциях с undefined или пустыми
обёртками.
Часто бывает полезно проверять, что компонент имеет определённые
свойства. Например, можно создать метод hasProp, который
будет возвращать true, если у компонента есть указанное
свойство с заданным значением, и false в противном
случае.
ShallowWrapper.prototype.hasProp = function(propName, propValue) {
const props = this.props();
return props && props[propName] === propValue;
};
// Пример использования
const wrapper = shallow(<MyComponent someProp="value" />);
const result = wrapper.hasProp('someProp', 'value'); // true
В этом примере метод hasProp проверяет, существует ли
свойство с нужным именем и значением, что может быть полезно для
тестирования корректности пропсов.
Иногда требуется не только симулировать событие, но и проверять
состояние компонента после его срабатывания. Для этого можно создать
метод simulateAndAssert, который будет сначала симулировать
событие, а затем проверять изменение состояния компонента.
ShallowWrapper.prototype.simulateAndAssert = function(event, eventData, expectedState) {
this.simulate(event, eventData);
expect(this.state()).toEqual(expectedState);
};
// Пример использования
const wrapper = shallow(<MyComponent />);
wrapper.simulateAndAssert('click', { target: { value: 'new value' } }, { value: 'new value' });
Этот метод полезен, когда важно не только сымитировать действие, но и проверить его влияние на состояние компонента.
Для лучшей интеграции с тестовыми фреймворками, такими как Jest, можно создавать расширения, которые добавляют дополнительные утилиты, например, для проверки различных стилей или атрибутов элементов.
Пример: создание метода для проверки наличия атрибута
disabled у кнопки.
ShallowWrapper.prototype.hasDisabledAttribute = function() {
return this.props().disabled === true;
};
// Пример использования
const wrapper = shallow(<button disabled />);
expect(wrapper.hasDisabledAttribute()).toBe(true);
Этот метод позволит просто и быстро проверять наличие атрибутов у элементов, что упрощает процесс написания тестов.
Вместо того чтобы изменять прототип ShallowWrapper
напрямую, можно создать отдельные утилиты, которые будут работать с
объектами ShallowWrapper. Это может быть полезно, если
необходимо избежать глобальных изменений в прототипах, что позволяет
сохранять совместимость с другими частями проекта.
Пример утилиты для поиска дочерних элементов по классу:
function findChildByClass(wrapper, className) {
return wrapper.find(`.${className}`).first();
}
// Пример использования
const wrapper = shallow(<MyComponent />);
const child = findChildByClass(wrapper, 'child-class');
Этот подход позволяет создавать методы, которые работают с обёртками,
но не требуют изменения самого объекта ShallowWrapper, что
повышает гибкость и облегчает тестирование.
Использование дополнительных библиотек: Иногда
удобнее использовать дополнительные библиотеки для работы с Enzyme,
такие как enzyme-matchers или jest-enzyme. Эти
библиотеки добавляют новые методы для работы с компонентами, делая код
тестов более читаемым и лаконичным.
Обратите внимание на совместимость: Прежде чем
расширять функциональность ShallowWrapper, убедитесь, что
такие изменения не нарушат существующие тесты или другие методы работы с
Enzyme. Лучше создавать утилиты, чем модифицировать прототипы
непосредственно.
Не добавляйте излишней логики: Важно помнить,
что методы, добавляемые в ShallowWrapper, должны быть
максимально простыми и фокусироваться на конкретных задачах. Излишняя
логика или сложные проверки могут сделать тесты тяжёлыми для
понимания.
Использование моков и шпионов: Если ваши тесты зависят от методов или состояний, которые трудно протестировать напрямую, используйте моки или шпионов. Они могут помочь вам отслеживать поведение компонента и симулировать разные сценарии.
Расширение функциональности ShallowWrapper в Enzyme
позволяет значительно упростить написание тестов и сделать их более
гибкими. Однако важно сохранять баланс между расширяемостью и
сложностью, чтобы не сделать код трудным для поддержки и понимания.