Проверка стилей через style

При тестировании компонентов в 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 класс. Этот способ хорошо подходит для тестирования компонентов, стили которых зависят от классов, а не от инлайновых стилей.

Проверка стилей с использованием CSS-in-JS

В последние годы популярность приобрели библиотеки для стилизации компонентов, такие как 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.

Использование Enzyme для сложных сценариев

В сложных сценариях, когда компонент имеет сложную иерархию или когда стили меняются в зависимости от асинхронных действий (например, загрузка данных), важно убедиться, что тесты корректно учитывают все возможные изменения в состоянии компонента.

Пример компонента с асинхронным изменением стилей:

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), выбор методов тестирования будет варьироваться. Важно, чтобы тесты были как можно более точными и проверяли не только функциональность компонентов, но и их внешний вид, соответствующий ожидаемому результату.