При тестировании компонентов в JavaScript важно проверять не только их функциональность, но и внешний вид. В частности, для тестирования правильности применения стилей в компонентах React часто используется библиотека Enzyme. Проверка стилей позволяет убедиться, что визуальное оформление компонента соответствует ожидаемому в разных сценариях.
Для тестирования стилей с помощью Enzyme можно использовать несколько
подходов, наиболее популярным из которых является использование метода
prop или style.
В React стили могут быть заданы через объект style,
который применяется непосредственно к элементу через пропс. Такой подход
позволяет динамически изменять стили в зависимости от состояния
компонента.
const Button = ({ isActive }) => {
return (
<button
style={{
backgroundColor: isActive ? 'green' : 'red',
color: 'white',
padding: '10px',
}}
>
Click me
</button>
);
};
Для того чтобы проверить правильность применения стилей, можно
использовать Enzyme, чтобы получить доступ к пропсу style и
убедиться, что значения стилей соответствуют ожидаемым.
import { shallow } from 'enzyme';
import Button from './Button';
describe('Button component', () => {
it('should have green background when active', () => {
const wrapper = shallow(<Button isActive={true} />);
const button = wrapper.find('button');
const buttonStyle = button.prop('style');
expect(buttonStyle.backgroundColor).toBe('green');
});
it('should have red background when inactive', () => {
const wrapper = shallow(<Button isActive={false} />);
const button = wrapper.find('button');
const buttonStyle = button.prop('style');
expect(buttonStyle.backgroundColor).toBe('red');
});
});
В этом примере используется метод prop('style'), чтобы
получить объект стилей, применяемый к кнопке. Затем проверяется, что
значение backgroundColor соответствует ожидаемому в
зависимости от состояния компонента.
Часто стили не задаются напрямую через объект style, а
применяются с помощью CSS классов. В таких случаях для проверки нужно
удостовериться, что компоненты имеют правильные классы в зависимости от
состояния.
const Button = ({ isActive }) => {
return (
<button className={isActive ? 'active' : 'inactive'}>
Click me
</button>
);
};
Для того чтобы проверить наличие соответствующего класса, можно
использовать Enzyme и метод hasClass.
import { shallow } from 'enzyme';
import Button from './Button';
describe('Button component', () => {
it('should have class "active" when active', () => {
const wrapper = shallow(<Button isActive={true} />);
expect(wrapper.find('button').hasClass('active')).toBe(true);
});
it('should have class "inactive" when inactive', () => {
const wrapper = shallow(<Button isActive={false} />);
expect(wrapper.find('button').hasClass('inactive')).toBe(true);
});
});
Здесь мы используем метод hasClass, чтобы проверить, что
элемент имеет ожидаемый CSS класс. Этот способ хорошо подходит для
тестирования компонентов, стили которых зависят от классов, а не от
инлайновых стилей.
В последние годы популярность приобрели библиотеки для стилизации
компонентов, такие как styled-components и
emotion, которые позволяют описывать стили непосредственно
в JavaScript. При таком подходе тестирование стилей может быть сложнее,
так как стили генерируются динамически.
styled-components:import styled from 'styled-components';
const Button = styled.button`
background-color: ${(props) => (props.isActive ? 'green' : 'red')};
color: white;
padding: 10px;
`;
export default Button;
В случае с styled-components проверка инлайновых стилей
будет немного сложнее, так как компоненты теперь генерируют динамические
классы, которые добавляются к элементам в процессе рендеринга. Для
тестирования можно использовать методы Enzyme, такие как
prop('className') или find в сочетании с
CSS-селекторами.
styled-components:import { shallow } from 'enzyme';
import Button from './Button';
describe('Button component', () => {
it('should have green background when active', () => {
const wrapper = shallow(<Button isActive={true} />);
const button = wrapper.find('button');
expect(button.prop('className')).toContain('active');
});
it('should have red background when inactive', () => {
const wrapper = shallow(<Button isActive={false} />);
const button = wrapper.find('button');
expect(button.prop('className')).toContain('inactive');
});
});
В этом примере используется проверка на содержание определённых
классов, которые генерируются автоматически библиотекой
styled-components.
В сложных сценариях, когда компонент имеет сложную иерархию или когда стили меняются в зависимости от асинхронных действий (например, загрузка данных), важно убедиться, что тесты корректно учитывают все возможные изменения в состоянии компонента.
const Button = ({ isLoading }) => {
return (
<button
style={{
backgroundColor: isLoading ? 'gray' : 'blue',
color: 'white',
}}
>
{isLoading ? 'Loading...' : 'Click me'}
</button>
);
};
Для тестирования такого компонента с асинхронным состоянием можно
использовать методы setState и update, чтобы
проверить, что стили обновляются правильно после изменения
состояния.
import { shallow } from 'enzyme';
import Button from './Button';
describe('Button component', () => {
it('should have gray background while loading', () => {
const wrapper = shallow(<Button isLoading={true} />);
expect(wrapper.find('button').prop('style').backgroundColor).toBe('gray');
});
it('should have blue background when not loading', () => {
const wrapper = shallow(<Button isLoading={false} />);
expect(wrapper.find('button').prop('style').backgroundColor).toBe('blue');
});
});
Здесь важно, чтобы тесты корректно отслеживали изменения состояния компонента и проверяли, что стили обновляются в зависимости от новых пропсов.
Проверка стилей в React-компонентах с использованием Enzyme является важной частью тестирования UI. В зависимости от того, как стили применяются (инлайн, через классы или с использованием CSS-in-JS), выбор методов тестирования будет варьироваться. Важно, чтобы тесты были как можно более точными и проверяли не только функциональность компонентов, но и их внешний вид, соответствующий ожидаемому результату.