Understanding getBy, queryBy, and findBy in React Testing Library

Last week, I was tasked with upgrading Jest from version 26 to 29. During this process, I took a closer look at the tests and realized that the most frequently used features are the query methods: getBy, queryBy, findBy, and their All variations.

At first glance, these queries might seem confusing due to their names or translations into other languages. This post will help you understand when and how to use them with clear examples.

getBy

Use when the element must exist in the DOM immediately.

getBy.test.js
1import { render, screen } from '@testing-library/react';
2test('renders a submit button', () => {
3 render(<button>Submit</button>);
4 const button = screen.getByText(/submit/i); // Case-insensitive match
5 expect(button).toBeInTheDocument();
6});

queryBy

Use when the element might not exist, and you want to check safely.

queryBy.test.js
1import { render, screen } from '@testing-library/react';
2test('does not render a cancel button initially', () => {
3 render(<div></div>);
4 const button = screen.queryByText(/cancel/i); // Safe query
5 expect(button).toBeNull();
6});

findBy

Use when the element is rendered asynchronously after some event.

ComponentWithAsyncData.jsx
1import React, { useEffect, useState } from 'react';
2
3const ComponentWithAsyncData = () => {
4const [data, setData] = useState<string | null>(null);
5
6 useEffect(() => {
7 const fetchData = async () => {
8 // Simulate an async data fetch
9 await new Promise((resolve) => setTimeout(resolve, 1000));
10 setData('Data loaded!');
11 };
12 fetchData();
13
14 }, []);
15
16 return (
17 <div>{data ? <p>{data}</p> : <p>Loading...</p>}</div>
18 );
19
20};
findBy.test.js
1import { render, screen } from '@testing-library/react';
2test('displays a message after data loads', async () => {
3 render(<ComponentWithAsyncData />);
4 const message = await screen.findByText(/data loaded!/i); // Wait for async rendering
5 expect(message).toBeInTheDocument();
6});

Common Mistakes to Avoid:

"Mistakes in selecting query methods can lead to flaky or failing tests. Understanding their nuances ensures that your tests remain robust and user-focused."

  • Using getBy for elements that might not exist: If the element might not be present in the DOM, prefer using queryBy. queryBy returns null if the element isn't found, whereas getBy will throw an error if the element is absent, causing unnecessary test failures.
  • Ignoring asynchronous rendering: If the element is rendered after an event or a delay (e.g., data fetching), make sure to use findBy. It will automatically wait for the element to appear, preventing issues with asserting before the DOM is updated.

Conclusion

Understanding getBy, queryBy, findBy, and their All variants can make your tests more precise and effective. Use them thoughtfully to align with how users interact with your UI.

Check out the React Testing Library documentation for more tips and advanced usage.