Enzyme предоставляет мощные инструменты для работы с компонентами React на уровне их структуры и состояния. Одним из наиболее часто встречающихся требований при тестировании интерфейсов является проверка условных стилей и классов. Это позволяет удостовериться, что компоненты корректно реагируют на пропсы, состояние или события, меняя отображение и поведение элементов.
В React часто используются условные классы для изменения внешнего вида компонента:
function Button({ isPrimary, isDisabled }) {
return (
<button className={`btn ${isPrimary ? 'btn-primary' : 'btn-secondary'} ${isDisabled ? 'disabled' : ''}`}>
Click me
</button>
);
}
Enzyme позволяет проверить наличие этих классов с помощью методов
hasClass и find:
import { shallow } from 'enzyme';
const wrapper = shallow(<Button isPrimary={true} isDisabled={false} />);
expect(wrapper.hasClass('btn')).toBe(true);
expect(wrapper.hasClass('btn-primary')).toBe(true);
expect(wrapper.hasClass('disabled')).toBe(false);
Ключевой момент: hasClass проверяет
класс на корневом элементе, тогда как метод find позволяет
искать вложенные элементы по селекторам и проводить проверку классов на
них:
const wrapper = shallow(<Button isPrimary={false} isDisabled={true} />);
const button = wrapper.find('button');
expect(button.hasClass('btn-secondary')).toBe(true);
expect(button.hasClass('disabled')).toBe(true);
Иногда классы добавляются через библиотеку classnames
или напрямую через условные выражения:
import classNames from 'classnames';
function Alert({ type }) {
const alertClass = classNames('alert', {
'alert-success': type === 'success',
'alert-error': type === 'error'
});
return <div className={alertClass}>Message</div>;
}
Тестирование таких компонентов требует проверки нескольких вариантов пропсов:
const wrapperSuccess = shallow(<Alert type="success" />);
expect(wrapperSuccess.hasClass('alert-success')).toBe(true);
expect(wrapperSuccess.hasClass('alert-error')).toBe(false);
const wrapperError = shallow(<Alert type="error" />);
expect(wrapperError.hasClass('alert-error')).toBe(true);
expect(wrapperError.hasClass('alert-success')).toBe(false);
Особенность: classnames объединяет
классы динамически, поэтому важно проверять конкретные комбинации для
различных условий.
prop('style')В некоторых случаях стили передаются через inline-объекты:
function Box({ isHighlighted }) {
return <div style={{ backgroundColor: isHighlighted ? 'yellow' : 'white' }}>Content</div>;
}
Enzyme позволяет получить объект стилей через метод
prop:
const wrapper = shallow(<Box isHighlighted={true} />);
expect(wrapper.prop('style')).toHaveProperty('backgroundColor', 'yellow');
const wrapperNormal = shallow(<Box isHighlighted={false} />);
expect(wrapperNormal.prop('style')).toHaveProperty('backgroundColor', 'white');
Важно: Прямое сравнение объектов стилей может быть
ненадёжным, если объект создаётся динамически. Использование
toHaveProperty обеспечивает точечную проверку конкретного
свойства.
Часто компоненты используют одновременно классы и inline-стили. Для
таких случаев тесты могут комбинировать проверки hasClass и
prop('style'):
function Card({ isSelected }) {
return (
<div
className={`card ${isSelected ? 'selected' : ''}`}
style={{ borderColor: isSelected ? 'blue' : 'gray' }}
>
Card Content
</div>
);
}
const wrapper = shallow(<Card isSelected={true} />);
expect(wrapper.hasClass('selected')).toBe(true);
expect(wrapper.prop('style')).toHaveProperty('borderColor', 'blue');
При тестировании событий, влияющих на классы, используют методы
simulate и последующую проверку состояния:
class Toggle extends React.Component {
state = { active: false };
toggle = () => this.setState({ active: !this.state.active });
render() {
return <button className={this.state.active ? 'active' : ''} onCl ick={this.toggle}>Toggle</button>;
}
}
const wrapper = shallow(<Toggle />);
const button = wrapper.find('button');
expect(button.hasClass('active')).toBe(false);
button.simulate('click');
expect(wrapper.find('button').hasClass('active')).toBe(true);
Вывод: Enzyme позволяет контролировать как
статические, так и динамические классы и стили, используя комбинацию
методов hasClass, prop, find и
simulate. Такой подход обеспечивает полное покрытие
условной логики отображения компонентов.
find,
чтобы исключить случайные совпадения.toHaveProperty для стилей вместо полного
сравнения объектов.simulate
и последующую проверку состояния компонента.Эти подходы обеспечивают детальное тестирование условной визуальной логики и повышают стабильность тестового покрытия.