React Testing Library предоставляет удобные методы для поиска
элементов на странице, однако понимание различий между
getBy, queryBy и findBy
критически важно для написания корректных и надёжных тестов. Эти три
паттерна различаются по поведению при отсутствии элементов, по
синхронности и по интеграции с асинхронными сценариями.
getBy —
немедленный поиск с исключениемМетоды getBy* предназначены для синхронного
поиска элемента и гарантируют, что элемент существует. Если
элемент не найден, библиотека выбрасывает исключение.
Это делает их удобными для случаев, когда элемент обязателен на
момент рендеринга.
import { render, screen } from '@testing-library/react';
import MyComponent from './MyComponent';
test('отображает кнопку отправки', () => {
render(<MyComponent />);
const button = screen.getByRole('button', { name: /отправить/i });
expect(button).toBeInTheDocument();
});
Особенности getBy:
TestingLibraryElementError, если элемент не
найден.queryBy —
безопасный поиск без исключенийМетоды queryBy* также синхронные, но не бросают
исключение, если элемент не найден. Вместо этого возвращают
null. Это делает их полезными для проверки
отсутствия элементов или элементов, которые могут быть
динамически удалены.
test('не отображает сообщение об ошибке по умолчанию', () => {
render(<MyComponent />);
const errorMessage = screen.queryByText(/ошибка/i);
expect(errorMessage).toBeNull();
});
Особенности queryBy:
findBy —
асинхронный поиск с ожиданиемМетоды findBy* предназначены для асинхронного
поиска элементов. Они возвращают Promise,
который разрешается, когда элемент появляется в DOM, либо отклоняется с
ошибкой, если элемент не появляется в течение заданного таймаута (по
умолчанию 1000 мс).
import userEvent from '@testing-library/user-event';
test('появляется сообщение после клика', async () => {
render(<MyComponent />);
const button = screen.getByRole('button', { name: /показать сообщение/i });
await userEvent.click(button);
const message = await screen.findByText(/сообщение отображено/i);
expect(message).toBeInTheDocument();
});
Особенности findBy:
Promise.getBy с ожиданием появления
элемента.| Паттерн | Синхронность | Поведение при отсутствии | Использование |
|---|---|---|---|
getBy |
Синхронно | Ошибка | Обязательные элементы |
queryBy |
Синхронно | Возврат null |
Проверка отсутствия или условных элементов |
findBy |
Асинхронно | Промис с ошибкой | Динамически появляющиеся элементы |
getBy, когда элемент
должен существовать сразу после рендера и отсутствие его является
ошибкой.queryBy, чтобы проверять,
что элемент не отображается в DOM или его наличие не
гарантировано.findBy, когда элемент
появляется асинхронно, например, после клика, задержки
или запроса к серверу.getBy для элементов, которые
появляются асинхронно. Это приведёт к неожиданным падениям
теста.queryBy там, где требуется проверить
наличие элемента. В этом случае тест может пройти даже если элемент
отсутствует.findBy, что часто
приводит к ошибкам промиса или таймаута.getAllBy, queryAllBy,
findAllBy расширяют поведение для множественных
элементов, сохраняя логику каждого паттерна:
getAllBy* — синхронно, ошибка при отсутствии
элементов.queryAllBy* — синхронно, возвращает пустой массив при
отсутствии.findAllBy* — асинхронно, промис отклоняется, если
элементы не появляются.Это позволяет гибко комбинировать подходы для проверки как одного, так и множества элементов.
Понимание различий между getBy, queryBy и
findBy критически важно для корректного проектирования
тестов в React Testing Library. Синхронные методы обеспечивают проверку
обязательных элементов и их отсутствия, а асинхронные методы позволяют
безопасно работать с динамическим контентом, минимизируя ложные
срабатывания и нестабильность тестов.