Observation regarding RTL getby
and findby
interchangeability
by Roy Revelt · posted on · reacttestingjsts
At first glance, it seems that React Testing Library (abbreviated RTL) await waitFor + get
can be replaced with find
everywhere, but it’s not so.
Consider the following test:
it("should have the box disabled", async () => {
render(<SomeComponent />);
await waitFor(() => {
expect(screen.getByTestId("box")).toBeDisabled();
});
});
In human language, we’re instructing Jest:
“look again and again for a disabled box.”
It might be tempting to replace waitfor
+ get
with find
to trim two lines of code:
it("should have the box disabled", async () => {
render(<SomeComponent />);
expect(await screen.findByTestId("box")).toBeDisabled();
});
But that would not work because we’re instructing Jest to:
“Look again and again for the box. When you find it, check that it is disabled.”
The test fails because instead of awaiting for the “disabled” state, we await only for presence — but the component has been present from the start — so the test does not wait for the component to become “disabled”.
Takeaway
The findby
is interchangeable with waitfor + getby
for “wait until it appears” scenarios only. The two are not interchangeable if we’re asserting any features that appear asynchronously on an already-present element.
That’s probably one of the reasons why the lint rule testing-library/prefer-find-by
doesn’t extend to all RTL queries.