Поиск по типу компонента

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

В Enzyme поиск компонентов осуществляется через методы, которые позволяют искать элементы по типам, таким как классы, функции и т. д. Разберёмся, как использовать эти методы и какие типы поиска они поддерживают.

Метод find

Метод find является основным инструментом для поиска элементов в дереве компонентов, и позволяет искать компоненты по их типу. При этом поиск может быть выполнен как по строкам (для поиска по селекторам CSS), так и по компонентам React.

const wrapper = shallow(<MyComponent />);
const button = wrapper.find('button');

В примере выше происходит поиск всех элементов <button> внутри компонента MyComponent. Метод find возвращает экземпляр объекта ShallowWrapper, с которым можно выполнять дальнейшие операции, например, проверку количества найденных элементов, их свойств или событий.

Поиск компонентов по типу

Enzyme позволяет искать компоненты по типу, что является одним из его основных преимуществ. Тип компонента может быть строкой (например, 'div', 'span', 'button'), функцией (например, компонентом React) или классом (например, MyComponent).

Пример поиска компонента по типу:

const wrapper = shallow(<MyComponent />);
const myComponent = wrapper.find(MyComponent);

В данном случае будет осуществлён поиск дочернего компонента MyComponent внутри компонента, с которым работает тест. Это особенно полезно для проверки взаимодействия между компонентами.

Поиск по типу с использованием контекста

Если компонент использует контекст, можно искать компоненты, которые используют этот контекст. Например, если компонент оборачивает контекст в своем дереве, поиск дочернего компонента можно выполнить, передав сам компонент в метод find.

const wrapper = mount(
  <MyContext.Provider value="test">
    <MyComponent />
  </MyContext.Provider>
);

const myComponent = wrapper.find(MyComponent);

В этом примере, контекст будет доступен для компонента MyComponent, и его можно найти с помощью метода find.

Поиск по компонентам, основанным на функции

Если компонент является функцией, поиск по типу будет работать аналогично поиску по классу. Например, если у нас есть функциональный компонент, и нужно найти его внутри родительского компонента:

const FunctionalComponent = () => <div>Test</div>;

const wrapper = shallow(<ParentComponent />);
const functionalComponent = wrapper.find(FunctionalComponent);

Здесь будет выполнен поиск всех экземпляров компонента FunctionalComponent, вложенных в ParentComponent.

Поиск с учётом свойств

Для поиска по типу и при этом учитывая определённые свойства компонента, можно использовать более сложные селекторы. Например, если необходимо найти компонент с определённым атрибутом или состоянием:

const wrapper = shallow(<MyComponent someProp="value" />);
const element = wrapper.find('[someProp="value"]');

В этом примере будет найден элемент, у которого свойство someProp равно "value". Такой подход полезен, если компоненты имеют разные конфигурации, и нужно тестировать поведение при изменении их свойств.

Поиск по типу в смешанных деревьях компонентов

Когда дерево компонентов состоит из различных типов элементов, можно комбинировать поиск по типу и по атрибутам для более точного поиска.

const wrapper = shallow(
  <ParentComponent>
    <ChildComponent className="special" />
  </ParentComponent>
);

const child = wrapper.find(ChildComponent).filterWhere(node => node.hasClass('special'));

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

Использование containsMatchingElement для более точного поиска

Метод containsMatchingElement позволяет найти компоненты, которые содержат дочерние элементы, соответствующие определённому типу. Это может быть полезно, если нужно проверить, что компонент содержит определённый элемент с ожидаемыми характеристиками.

const wrapper = shallow(<MyComponent />);
const result = wrapper.containsMatchingElement(<button>Click Me</button>);

Здесь происходит проверка, содержит ли компонент кнопку с текстом "Click Me". Такой поиск полезен, если нужно проверить, что компоненты отображаются правильно в зависимости от состояния или свойств.

Режимы поиска: shallow, mount и render

Поиск по типу работает по-разному в зависимости от метода рендеринга компонента:

  • shallow: выполняет поиск только на первом уровне компонента, без рендеринга его дочерних компонентов.
  • mount: выполняет полный рендеринг компонента, включая его дочерние компоненты.
  • render: генерирует HTML-строку компонента, что подходит для тестирования результата рендеринга.

Выбор метода рендеринга зависит от того, какой уровень тестирования требуется. Например, если нужно тестировать только внешний вид компонента без учёта его внутренних состояний, можно использовать shallow.

Использование state и prop в поиске

Иногда необходимо искать компоненты, которые находятся в определённом состоянии или имеют заданные свойства. Для этого можно использовать методы, такие как state и prop, чтобы фильтровать найденные элементы.

const wrapper = shallow(<MyComponent />);
const activeButton = wrapper.find('button').filterWhere(node => node.prop('disabled') === false);

Здесь поиск ограничен только теми кнопками, которые не отключены (свойство disabled имеет значение false).

Заключение

Поиск по типу компонента является неотъемлемой частью тестирования в Enzyme. Это мощный инструмент для проверки, что компоненты рендерятся и взаимодействуют друг с другом в соответствии с требованиями. Использование различных методов поиска и фильтрации позволяет тестировщикам легко находить нужные элементы, повышая точность и эффективность тестов.