Моки компонентов Ant Design

Мокирование компонентов в Ant Design необходимо для упрощения разработки и тестирования интерфейсов. Библиотека предоставляет множество высокоуровневых компонентов с собственными сложными внутренними состояниями. При тестировании или при создании прототипов часто требуется заменить реальный компонент на упрощённый мок, чтобы изолировать логику приложения и избежать зависимости от сложных визуальных элементов.

Ключевые цели мокирования:

  • Уменьшение времени рендеринга сложных компонентов.
  • Изоляция логики приложения от сторонних библиотек.
  • Возможность управления состоянием компонента в тестах.
  • Создание предсказуемого поведения для автоматизированных тестов.

Использование Jest и React Testing Library для моков

Наиболее популярным подходом является применение Jest для создания моков компонентов Ant Design совместно с React Testing Library. Основная техника заключается в замене оригинального импорта компонента на фиктивный:

import { Button } from 'antd';

jest.mock('antd', () => {
  const originalModule = jest.requireActual('antd');
  return {
    ...originalModule,
    Button: (props) => <button {...props}>{props.children}</button>,
  };
});

Пояснения:

  • jest.requireActual('antd') сохраняет все остальные компоненты Ant Design без изменений.
  • Компонент Button заменяется на простой HTML <button>, сохраняя возможность передачи props и children.
  • Такой подход позволяет тестировать логику обработки событий без необходимости рендерить сложные стили и внутренние механизмы Ant Design.

Мокирование сложных компонентов с внутренним состоянием

Некоторые компоненты, такие как Select, Table, DatePicker, имеют собственное состояние и сложные события. Для них простого HTML-заменителя недостаточно — требуется имитация API компонента:

jest.mock('antd', () => {
  const originalModule = jest.requireActual('antd');

  const MockSelect = ({ children, onChange, value }) => (
    <sel ect value={value} onCha nge={(e) => onChange?.(e.target.value)}>
      {children}
    </select>
  );

  return {
    ...originalModule,
    Select: MockSelect,
  };
});

Особенности:

  • Обработчик onChange вызывается с правильным аргументом.
  • Сохраняется интерфейс value, что позволяет корректно тестировать контролируемые компоненты.
  • Такой мок можно использовать для эмуляции выбора в таблицах или фильтров формы.

Создание универсального мок-компонента

Для большого проекта удобно создать утилиту для мокирования любых компонентов Ant Design. Это позволяет централизованно управлять поведением мока и минимизировать повторяющийся код:

const createAntdMock = (overrides = {}) => {
  const antd = jest.requireActual('antd');
  const mockComponents = {};

  Object.keys(antd).forEach((key) => {
    mockComponents[key] = overrides[key] || ((props) => <div>{props.children}</div>);
  });

  return mockComponents;
};

jest.mock('antd', () => createAntdMock({
  Button: (props) => <button {...props}>{props.children}</button>,
  Select: ({ children, onChange, value }) => (
    <select value={value} onCha nge={(e) => onChange?.(e.target.value)}>
      {children}
    </select>
  ),
}));

Преимущества такого подхода:

  • Легко добавлять новые моки без изменения всех тестов.
  • Позволяет создавать предсказуемые визуальные заглушки.
  • Поддерживает все ключевые API компонентов, необходимые для тестирования логики.

Мокирование стилизованных компонентов

Иногда требуется сохранять стили компонентов Ant Design при мокировании, чтобы тесты визуально не ломались и можно было проверять классы CSS:

jest.mock('antd', () => {
  const originalModule = jest.requireActual('antd');
  const MockButton = (props) => <button className={`antd-btn ${props.className}`}>{props.children}</button>;
  return { ...originalModule, Button: MockButton };
});

Особенности:

  • Добавляется базовый класс antd-btn, чтобы можно было проверять наличие CSS-классов в тестах.
  • Позволяет контролировать визуальные состояния, такие как disabled или loading, через props.

Мокирование модальных окон и уведомлений

Компоненты вроде Modal или notification сложно тестировать напрямую, так как они рендерятся вне основного DOM-дерева. Для них создаются отдельные моки:

import { notification } fr om 'antd';

jest.mock('antd', () => {
  const originalModule = jest.requireActual('antd');
  return {
    ...originalModule,
    notification: {
      open: jest.fn(),
      success: jest.fn(),
      error: jest.fn(),
    },
  };
});

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

  • Не требуется отображение реального модального окна.
  • Можно проверять вызовы методов notification.success и notification.error.
  • Позволяет тестировать бизнес-логику, вызывающую уведомления, без визуального рендеринга.

Советы по эффективному мокированию

  • Изолировать только необходимые компоненты. Мокировать весь Ant Design не всегда нужно — достаточно отдельных элементов.
  • Сохранять интерфейс оригинала. Любое отклонение может привести к ложноположительным или ложноотрицательным результатам тестов.
  • Использовать универсальные функции мокирования для крупных проектов. Это уменьшает дублирование кода.
  • Мокировать стили только при необходимости. Для большинства тестов логики достаточно функциональных заглушек без CSS.
  • Проверять события и props. Моки должны корректно вызывать переданные колбэки и управлять значениями value или checked.

Мокирование компонентов Ant Design является критическим инструментом при построении надёжной тестовой среды и ускоряет разработку сложных интерфейсов, позволяя сосредоточиться на логике приложения, а не на визуальных деталях.