Queries: getBy, queryBy, findBy

В Jest, для работы с элементами DOM используется библиотека Testing Library, которая предоставляет набор утилит для поиска элементов. Эти утилиты часто используются для выполнения запросов и взаимодействия с компонентами в тестах, моделируя поведение пользователя. Основные методы для поиска элементов — это getBy, queryBy и findBy. Каждый из этих методов имеет свои особенности, которые определяют, как и когда они могут быть использованы.

getBy

Метод getBy используется для поиска элемента, который должен быть найден в DOM. Если элемент не найден, будет выброшено исключение.

Особенности:

  • Возвращает найденный элемент.
  • Если элемент не найден, тест завершится с ошибкой.
  • Используется, когда элемент обязательно должен быть в DOM.

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

test('поиск элемента по тексту', () => {
  render(<MyComponent />);
  const element = screen.getByText('Привет, мир!');
  expect(element).toBeInTheDocument();
});

В данном примере метод getByText ищет элемент с текстом “Привет, мир!”. Если элемент не найден, тест не пройдет.

Метод getBy имеет различные варианты поиска, например:

  • getByText — поиск по тексту.
  • getByRole — поиск по роли элемента (например, кнопка или заголовок).
  • getByLabelText — поиск по тексту метки, связанной с элементом формы.
  • getByPlaceholderText — поиск по тексту в плейсхолдере.

queryBy

Метод queryBy работает аналогично getBy, но с одной ключевой разницей: если элемент не найден, не будет выброшено исключение. Вместо этого он вернет null.

Особенности:

  • Возвращает найденный элемент или null.
  • Если элемент не найден, не выбрасывает ошибку.
  • Полезен, когда элемент может не существовать на странице, и это нормально.

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

test('поиск элемента, который может не существовать', () => {
  render(<MyComponent />);
  const element = screen.queryByText('Нет такого текста');
  expect(element).toBeNull();
});

В этом примере, так как элемент с текстом “Нет такого текста” отсутствует, метод queryByText вернет null, и тест пройдет успешно.

Метод queryBy также имеет варианты, аналогичные getBy, такие как:

  • queryByText — поиск по тексту.
  • queryByRole — поиск по роли.
  • queryByLabelText — поиск по метке.

findBy

Метод findBy используется для поиска элемента, который должен появиться в DOM через некоторое время, например, после асинхронного действия. В отличие от getBy и queryBy, findBy возвращает Promise, который разрешается, когда элемент появляется в DOM, или отклоняется, если элемент не найден за указанное время.

Особенности:

  • Возвращает Promise.
  • Используется для поиска асинхронных элементов.
  • Если элемент не появляется в течение заданного времени (по умолчанию 1000 мс), тест завершится с ошибкой.

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

test('поиск элемента, который появляется после асинхронного события', async () => {
  render(<MyComponent />);
  const element = await screen.findByText('Загруженный элемент');
  expect(element).toBeInTheDocument();
});

В этом примере компонент загружает элемент с текстом “Загруженный элемент” асинхронно. Метод findByText ждет появления этого элемента в DOM и продолжает выполнение теста только после его нахождения.

Метод findBy имеет варианты, аналогичные getBy и queryBy, включая:

  • findByText — асинхронный поиск по тексту.
  • findByRole — асинхронный поиск по роли.
  • findByLabelText — асинхронный поиск по метке.

Когда использовать каждый метод

  1. getBy следует использовать, когда элемент обязательно должен быть в DOM на момент выполнения теста. Этот метод полезен, когда вы уверены, что элемент уже существует и будет найден. Например, при проверке, что кнопка или заголовок рендерится сразу после загрузки компонента.

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

  3. findBy используется для поиска элементов, которые могут появиться с задержкой, например, после асинхронных запросов или эффектов. Это основной выбор, когда нужно дождаться, чтобы элемент стал доступен в DOM, как это происходит, например, в случае с запросами на сервер.

Важные аспекты использования

  • Все методы поиска в Testing Library стремятся к тому, чтобы тесты были максимально похожи на реальные действия пользователей. Поэтому методы ориентированы на поиск элементов через текст, роли и другие атрибуты, которые видит пользователь.
  • Разница между getBy, queryBy и findBy заключается в том, как они обрабатывают отсутствие элементов. Выбор метода зависит от того, насколько строго вы хотите проверять наличие элементов в тесте.
  • Важно помнить, что использование асинхронных методов (например, findBy) связано с дополнительным временем ожидания, что может быть важно при тестировании работы UI с сетью или задержками.

Заключение

Методы getBy, queryBy и findBy являются основными инструментами для работы с элементами в тестах с использованием Testing Library в Jest. Они предоставляют гибкие и мощные способы поиска элементов в зависимости от того, как они появляются в DOM и какие условия теста предполагаются. Правильное использование этих методов позволяет создавать устойчивые и точные тесты, отражающие реальное поведение пользователя.