What's the difference between getByText vs findByText vs queryByText in testing-library?
Asked Answered
P

1

18

There are multiple ways of getting an element's text content: getByText vs findByText vs queryByText.
Sometimes I get confused about which one to use.
I have the following example in react-native:

it('should render children', () => {
  const mockedChildComponentTxt = 'Children are rendered';
  const { getByText, findByText, queryByText } = render(
    <MyProvider>
      <div>{mockedChildComponentTxt}</div>
    </MyProvider>,
  );
  expect(queryByText(mockedChildComponentTxt)).toBeTruthy()
});

queryByText and getByText are failing, but findByText works.

debug() resulting in:

<RNCSafeAreaView
    onInsetsChange={[Function anonymous]}
    style={
      Object {
        "flex": 1,
      }
    }
>
    <div>
      Children are rendered
    </div>
</RNCSafeAreaView>

Why findByText works in the above example, but getByText and queryByText fail?

Partiality answered 17/7, 2023 at 13:55 Comment(1)
queryBy vs getBy: getBy throws an error if the element is not found, while queryBy returns null if the element is not found. So, if you're checking for the presence of an element that might not be there, use queryBy. If you're certain the element should exist and want the test to fail if it doesn't, use getBy.Partiality
N
21

findBy

findBy queries return a promise which resolves when a matching element is found. The promise is rejected if no elements match or if more than one match is found after a default timeout of 1000 ms. If you need to find more than one element, then use findAllBy.

getBy

getBy queries return the first matching node for a query, and throw an error if no elements match or if more than one match is found. If you need to find more than one element, then use getAllBy.

queryBy

queryBy queries return the first matching node for a query, and return null if no elements match. This is useful for asserting an element that is not present. This throws if more than one match is found (use queryAllBy instead).

docs

Here in your example the rendered component contains the text "Children are rendered," but it seems that it might not be available in the DOM immediately.
it's possible that the element is added to the DOM asynchronously after rendering, which is why getByText and queryByText are not able to find it immediately. however, findByText works because it waits for the element to appear in the DOM due to its asynchronous nature

findBy queries return a promise which resolves when a matching element is found.

and when it finds the element, the test passes.

Necrophilia answered 17/7, 2023 at 14:19 Comment(2)
Hi @Hatana, thank you for the answer, can you please explain why getByText doesn't work in my example given above?Partiality
@IsmoilShokirov have a lookNecrophilia

© 2022 - 2024 — McMap. All rights reserved.