При работе с React часто используется концепция Higher-Order
Components (HOC) для повторного использования логики между
компонентами. HOC — это функция, которая принимает компонент и
возвращает новый компонент с расширенным функционалом. Важной частью
тестирования таких компонентов является проверка корректной передачи и
обработки props.
HOC может:
При тестировании нужно учитывать, что внутренний компонент получает уже измененные props, и именно их следует проверять.
Для тестирования 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.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); // значение по умолчанию
Если 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 переопределил значение
Некоторые 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");
HOC часто добавляет методы, например, обработчики событий. Их проверка состоит из двух частей:
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
Для поддержания чистоты тестирования важно различать:
Использование shallow позволяет изолировать
базовый компонент и убедиться, что HOC правильно передаёт
значения.
| Метод | Назначение |
|---|---|
.find(Component) |
Находит внутренний компонент для извлечения props |
.props() |
Получение всех props компонента |
.prop('name') |
Получение конкретного prop |
.setProps() |
Динамическая смена props для проверки реактивности HOC |
Эти методы позволяют создавать тесты, которые проверяют корректность передачи и модификации props, а также взаимодействие с компонентами верхнего уровня.
Такой подход позволяет убедиться, что HOC выполняет свою функцию корректной передачи и модификации props, что критично для поддержки больших и масштабируемых приложений на React.