В тестировании JavaScript-приложений важной частью является проверка взаимодействия компонентов с пользователем. Одним из таких взаимодействий являются события, которые могут происходить в различных частях пользовательского интерфейса: клики по кнопкам, ввод текста в форму, перемещение мыши и другие действия. В Jest для работы с событиями используется функционал, позволяющий не только отслеживать их, но и симулировать, имитируя реальные пользовательские действия.
События в JavaScript — это сигналы, которые генерируются браузером или пользователем для выполнения определённого действия в приложении. Эти события могут быть связаны с различными действиями, такими как:
События обрабатываются через обработчики событий, которые могут быть привязаны к элементам DOM. Для их проверки в тестах важно правильно смоделировать эти события, чтобы убедиться, что приложение правильно реагирует на действия пользователя.
@testing-library/react и симуляция событийJest часто используется вместе с библиотекой
@testing-library/react, которая предоставляет удобные
инструменты для тестирования React-компонентов. Одним из таких
инструментов является симуляция событий, позволяющая эмулировать
действия пользователя и проверять поведение компонентов в ответ на
них.
В @testing-library/react для симуляции событий
используется функция fireEvent, которая позволяет
отправлять различные события на элементы. Она поддерживает все основные
типы событий, такие как click, change,
input, submit и другие.
fireEventДля начала рассмотрим простой пример, где мы создаём кнопку, которая изменяет текст при клике:
import { render, fireEvent } from '@testing-library/react';
import MyComponent from './MyComponent';
test('изменяет текст при клике', () => {
const { getByText } = render(<MyComponent />);
const button = getByText('Нажми меня');
fireEvent.click(button);
const updatedText = getByText('Текст изменён');
expect(updatedText).toBeInTheDocument();
});
В этом примере мы:
MyComponent.fireEvent.click.fireEvent поддерживает множество типов событий, и каждый
из них используется для разных целей. Рассмотрим наиболее
распространённые:
click)Для симуляции клика по элементу используется метод
fireEvent.click. Этот метод используется для проверки, что
обработчик события, привязанный к элементу, срабатывает корректно.
fireEvent.click(button);
change, input)Когда пользователь вводит текст в форму, мы можем симулировать это
событие с помощью fireEvent.change или
fireEvent.input. Оба события связаны с изменением значения
в элементах формы, но между ними есть различия в поведении.
change — срабатывает, когда значение
поля изменилось и фокус с поля был потерян (например, когда пользователь
выходит из поля ввода).input — срабатывает при каждом
изменении значения поля (обычно используется для отслеживания ввода
текста).Пример симуляции ввода текста:
const input = getByLabelText('Имя');
fireEvent.change(input, { target: { value: 'Иван' } });
expect(input.value).toBe('Иван');
submit)Для симуляции отправки формы используется событие
submit. Это событие полезно, чтобы проверить, что форма
правильно обрабатывает отправку данных.
const form = getByTestId('my-form');
fireEvent.submit(form);
Интерактивность с элементами формы может включать фокусировку и
размытие (потерю фокуса). Для этих случаев можно использовать события
focus и blur.
const input = getByLabelText('Имя');
fireEvent.focus(input);
fireEvent.blur(input);
Симуляция событий в сочетании с асинхронными действиями, такими как
загрузка данных с сервера или обработка отложенных функций, требует
правильной организации тестов. Jest и
@testing-library/react предоставляют функции, которые
позволяют работать с асинхронными событиями.
Для асинхронных ожиданий в тестах следует использовать
waitFor, который позволяет дождаться выполнения действий до
того, как проверка будет выполнена.
import { waitFor } from '@testing-library/react';
test('загружает данные при клике', async () => {
const { getByText } = render(<MyComponent />);
const button = getByText('Загрузить данные');
fireEvent.click(button);
await waitFor(() => expect(getByText('Данные загружены')).toBeInTheDocument());
});
Здесь мы симулируем клик по кнопке, инициирующий асинхронную операцию, и ожидаем появления текста “Данные загружены”, что указывает на успешное завершение операции.
Иногда в тестах возникает необходимость симулировать более сложные
события, например, пользовательские. Для этого можно использовать
конструктор Event, чтобы создать событие и передать его в
элемент.
const event = new Event('myCustomEvent');
fireEvent(element, event);
Это полезно, когда нужно эмулировать события, которые не поддерживаются стандартными методами.
user-event для более реалистичных симуляцийБиблиотека @testing-library/user-event предоставляет
более высокоуровневые функции для симуляции пользовательских действий,
таких как ввод текста, клик, фокусировка и другие. Это более гибкий
инструмент, который лучше эмулирует поведение реальных пользователей по
сравнению с fireEvent.
Пример использования user-event для ввода текста:
import userEvent from '@testing-library/user-event';
const input = getByLabelText('Имя');
userEvent.type(input, 'Иван');
expect(input.value).toBe('Иван');
В некоторых случаях тесты могут требовать мокирования (подмены) событий для проверки работы системы в специфических условиях. Jest предоставляет удобные средства для мокирования функций, включая обработчики событий. Это особенно полезно при тестировании компонентов, которые реагируют на события в контексте взаимодействия с внешними системами или при проверке ошибок.
const mockHandler = jest.fn();
fireEvent.click(button);
expect(mockHandler).toHaveBeenCalled();
Симуляция событий в Jest — это мощный инструмент для тестирования
поведения интерфейса. Благодаря библиотекам
@testing-library/react и
@testing-library/user-event, тестирование пользовательских
действий стало проще и более эффективным. Правильная симуляция событий
позволяет глубже тестировать компоненты и улучшить качество программного
обеспечения, обеспечивая уверенность в том, что приложение правильно
реагирует на действия пользователя.