Что такое Enzyme и для чего он используется?react-74

Enzyme — это популярная библиотека для тестирования React-компонентов, разработанная Airbnb. Она предоставляет мощный и интуитивно понятный API для рендеринга, traversing (обхода) и манипулирования выводами React-компонентов в тестах.

Основные возможности

  1. Три уровня рендеринга:

    • shallow (поверхностный) — рендерит только сам компонент без дочерних
    • mount (полный) — рендерит компонент со всем DOM-деревом
    • render (статический) — рендерит в статический HTML
  2. jQuery-подобный API для поиска элементов:

    • find() — поиск по селекторам
    • simulate() — симуляция событий
    • props(), state() — доступ к пропсам и состоянию

Установка

Для работы с React 17+:

npm install --save-dev enzyme @wojtekmaj/enzyme-adapter-react-17

Настройка адаптера (в setupTests.js):

import Enzyme from 'enzyme';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';

Enzyme.configure({ adapter: new Adapter() });

Примеры использования

1. Shallow Rendering

Идеально для юнит-тестирования изолированных компонентов:

import { shallow } from 'enzyme';

function Button({ onClick, children }) {
  return <button onClick={onClick}>{children}</button>;
}

test('renders button with text', () => {
  const wrapper = shallow(<Button>Click me</Button>);
  expect(wrapper.find('button').text()).toEqual('Click me');
});

2. Full DOM Rendering

Необходим для тестирования lifecycle-методов и интеграции:

import { mount } from 'enzyme';

class Counter extends React.Component {
  state = { count: 0 };
  increment = () => this.setState({ count: this.state.count + 1 });

  render() {
    return (
      <div>
        <span className="count">{this.state.count}</span>
        <button className="increment" onClick={this.increment}>+</button>
      </div>
    );
  }
}

test('increments counter on click', () => {
  const wrapper = mount(<Counter />);
  wrapper.find('.increment').simulate('click');
  expect(wrapper.find('.count').text()).toBe('1');
});

3. Доступ к состоянию и пропсам

const wrapper = shallow(<User name="John" age={25} />);

// Проверка пропсов
expect(wrapper.props().name).toEqual('John');

// Проверка состояния
wrapper.setState({ isActive: true });
expect(wrapper.state().isActive).toBe(true);

Сравнение с React Testing Library

Особенность Enzyme React Testing Library (RTL)
Философия Тестирование реализации Тестирование поведения
Доступ к состоянию Да Нет
API стиль Императивный Декларативный
Рекомендация Устаревающий выбор Современный стандарт

Плюсы и минусы

Преимущества (+):

  • Более детальный контроль над компонентами
  • Возможность тестировать внутренние методы
  • Поддержка всех версий React

Недостатки (-):

  • Может приводить к хрупким тестам (brittle tests)
  • Меньше фокуса на тестировании пользовательского опыта
  • Требует дополнительных адаптеров для новых версий React

Миграция на RTL

Если вы начинаете новый проект, рекомендуется использовать React Testing Library. Для миграции:

// Старый тест на Enzyme
test('old enzyme test', () => {
  const wrapper = shallow(<Component />);
  wrapper.instance().handleClick();
  expect(wrapper.state().clicked).toBe(true);
});

// Новый тест на RTL
test('new RTL test', () => {
  render(<Component />);
  userEvent.click(screen.getByRole('button'));
  expect(screen.getByText('Clicked!')).toBeInTheDocument();
});

Резюмируем

Enzyme — это мощный инструмент для тестирования React-компонентов, который дает разработчику низкоуровневый доступ к внутренней работе компонентов. Хотя в новых проектах чаще используют React Testing Library, Enzyme остается важным инструментом, особенно для поддержки legacy-кода и сложных сценариев тестирования.