Тестирование props, передаваемых через HOC

При работе с React часто используется концепция Higher-Order Components (HOC) для повторного использования логики между компонентами. HOC — это функция, которая принимает компонент и возвращает новый компонент с расширенным функционалом. Важной частью тестирования таких компонентов является проверка корректной передачи и обработки props.

Основные принципы работы HOC

HOC может:

  1. Добавлять новые props — модифицировать или обогащать входной компонент дополнительными свойствами.
  2. Переопределять существующие props — изменять поведение компонента на основе внешнего контекста или состояния.
  3. Оборачивать компонент — добавлять обработчики событий, логику состояния или другие функциональные возможности.

При тестировании нужно учитывать, что внутренний компонент получает уже измененные props, и именно их следует проверять.

Настройка окружения с Enzyme

Для тестирования HOC используется Enzyme, библиотека для глубокого рендеринга и обхода компонентов:

import React from 'react';
import { shallow, mount } from 'enzyme';
import MyComponent from './MyComponent';
import withExtraProps from './withExtraProps';

Разница между shallow и mount критична:

  • shallow позволяет тестировать компонент изолированно, без рендеринга вложенных компонентов.
  • mount создаёт полноценный DOM и подходит для проверки взаимодействий и жизненного цикла HOC.

Тестирование передачи props

Проверка добавленных props

HOC часто добавляет новые свойства. Например, если HOC добавляет user и isLoggedIn:

const EnhancedComponent = withExtraProps(MyComponent);
const wrapper = shallow(<EnhancedComponent someProp="test" />);

Для проверки props можно использовать методы Enzyme:

const innerProps = wrapper.find(MyComponent).props();

expect(innerProps.someProp).toBe("test"); // исходный prop
expect(innerProps.user).toBeDefined();    // добавленный HOC prop
expect(innerProps.isLoggedIn).toBe(false); // значение по умолчанию
Проверка переопределения props

Если HOC модифицирует существующие props, важно убедиться, что их значение корректно:

const withModifiedProps = (Component) => (props) => {
  return <Component {...props} isLoggedIn={true} />;
};

const Enhanced = withModifiedProps(MyComponent);
const wrapper = shallow(<Enhanced isLoggedIn={false} />);
const innerProps = wrapper.find(MyComponent).props();

expect(innerProps.isLoggedIn).toBe(true); // HOC переопределил значение
Передача динамических props через контекст

Некоторые HOC используют контекст или Redux для передачи props. В таких случаях нужно симулировать контекст при тестировании:

import { Provider } from 'react-redux';
import configureStore from 'redux-mock-store';

const mockStore = configureStore([]);
const store = mockStore({ user: { name: "Alice" } });

const wrapper = mount(
  <Provider store={store}>
    <ConnectedComponent />
  </Provider>
);

const innerProps = wrapper.find(MyComponent).props();
expect(innerProps.user.name).toBe("Alice");

Тестирование коллбеков и функций в props

HOC часто добавляет методы, например, обработчики событий. Их проверка состоит из двух частей:

  1. Проверка наличия метода в props
  2. Проверка корректного вызова и побочных эффектов
const Enhanced = withExtraHandlers(MyComponent);
const wrapper = shallow(<Enhanced />);
const innerProps = wrapper.find(MyComponent).props();

expect(typeof innerProps.onClick).toBe("function");

innerProps.onClick(); // вызов функции
expect(wrapper.state("clicked")).toBe(true); // проверка побочного эффекта HOC

Разделение тестов HOC и внутреннего компонента

Для поддержания чистоты тестирования важно различать:

  • Тестирование HOC: проверка добавленных или изменённых props, состояния и коллбеков.
  • Тестирование базового компонента: проверка логики работы с переданными props.

Использование shallow позволяет изолировать базовый компонент и убедиться, что HOC правильно передаёт значения.

Полезные методы Enzyme для props HOC

Метод Назначение
.find(Component) Находит внутренний компонент для извлечения props
.props() Получение всех props компонента
.prop('name') Получение конкретного prop
.setProps() Динамическая смена props для проверки реактивности HOC

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

Рекомендации по структуре тестов HOC

  1. Создавать отдельные файлы для HOC — тесты не должны зависеть от реализации базового компонента.
  2. Проверять как исходные, так и добавленные props.
  3. Использовать shallow для базового тестирования и mount для проверки жизненного цикла.
  4. Тестировать динамические props и коллбеки, особенно если HOC управляет состоянием или контекстом.
  5. Не смешивать тесты HOC и внутреннего компонента, чтобы легче было локализовать ошибки.

Такой подход позволяет убедиться, что HOC выполняет свою функцию корректной передачи и модификации props, что критично для поддержки больших и масштабируемых приложений на React.