Создание вспомогательных функций

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


Функции для рендеринга компонентов

Enzyme предоставляет три основных метода рендеринга:

  • shallow – поверхностный рендеринг, при котором дочерние компоненты не рендерятся полностью. Позволяет изолировать тестируемый компонент.
  • mount – полный рендеринг компонента вместе с его деревом, включая жизненный цикл. Используется для интеграционных тестов.
  • render – статический рендеринг в HTML, полезен для проверки верстки и классов.

Вспомогательная функция для рендеринга обычно принимает компонент и props:

import { shallow, mount } from 'enzyme';

export const renderShallow = (Component, props = {}) => shallow(<Component {...props} />);
export const renderMount = (Component, props = {}) => mount(<Component {...props} />);

Такой подход позволяет централизованно менять стратегию рендеринга без изменения всех тестов.


Поиск элементов в компоненте

Часто нужно многократно искать одни и те же элементы, например кнопки или поля ввода. Вспомогательные функции упрощают этот процесс и повышают читаемость тестов:

export const findByTestAttr = (wrapper, attr) => wrapper.find(`[data-test="${attr}"]`);
export const findButton = (wrapper, text) => wrapper.find('button').filterWhere(node => node.text() === text);

Использование data-test атрибутов является стандартной практикой для создания селекторов, не зависящих от структуры DOM и классов.


Имитация событий

Enzyme позволяет вызывать события через метод simulate. Вспомогательные функции помогают унифицировать тестирование событий:

export const clickButton = (wrapper, attr) => {
    findByTestAttr(wrapper, attr).simulate('click');
};

export const changeInput = (wrapper, attr, value) => {
    findByTestAttr(wrapper, attr).simulate('change', { target: { value } });
};

Такой подход упрощает повторное использование и минимизирует ошибки при передаче событий.


Проверка состояния и пропсов

Вспомогательные функции позволяют централизованно проверять состояние компонентов или значения пропсов:

export const expectState = (wrapper, key, expected) => {
    expect(wrapper.state(key)).toBe(expected);
};

export const expectProp = (wrapper, key, expected) => {
    expect(wrapper.prop(key)).toBe(expected);
};

Использование таких функций делает тесты компактными и легко читаемыми, особенно при большом числе проверок.


Организация вспомогательных функций

  1. Создание отдельного файла – лучше хранить все функции в testUtils.js или enzymeHelpers.js, чтобы избежать дублирования.
  2. Группировка по типу действий – рендеринг, поиск, события, проверки.
  3. Документирование – краткие комментарии помогают понять назначение функции без необходимости изучать её реализацию.

Пример структуры файла:

// testUtils.js
export * from './renderHelpers';
export * from './findHelpers';
export * from './eventHelpers';
export * from './assertHelpers';

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

Функции должны быть максимально универсальными:

  • Принимать компонент и props для рендеринга.
  • Принимать селекторы и значения для поиска элементов и имитации событий.
  • Возвращать wrapper, чтобы можно было цепочкой вызывать дальнейшие проверки.

Пример:

export const renderAndFind = (Component, props, attr) => {
    const wrapper = renderMount(Component, props);
    return findByTestAttr(wrapper, attr);
};

Это позволяет в одном вызове создать компонент и сразу получить нужный элемент.


Интеграция с Jest

Вспомогательные функции легко интегрируются с Jest:

import { renderShallow, clickButton, expectState } from './testUtils';

test('кнопка увеличивает счетчик', () => {
    const wrapper = renderShallow(Counter);
    clickButton(wrapper, 'increment-btn');
    expectState(wrapper, 'count', 1);
});

Такой подход делает тесты выразительными и минимизирует повторяющийся код.


Применение фабрик для компонентов

Для сложных компонентов часто создают фабрики, которые возвращают компонент с набором стандартных props. В сочетании с вспомогательными функциями это позволяет быстро создавать разнообразные тестовые сценарии:

export const createUserForm = (overrides = {}) => ({
    username: 'testUser',
    password: '123456',
    ...overrides
});

В тесте:

const props = createUserForm({ password: 'abcdef' });
const wrapper = renderMount(UserForm, props);

Такой подход особенно удобен для компонентов с большим числом пропсов или сложной инициализацией.


Унификация тестов и поддержка

Использование вспомогательных функций позволяет стандартизировать тесты:

  • Упрощает рефакторинг компонентов.
  • Облегчает переход на новые версии Enzyme или React.
  • Снижает риск ошибок при копировании одинаковых блоков кода.

В результате тестовая база становится более стабильной и масштабируемой, а новые тесты создаются быстрее и проще.