reactjsreact-nativereact-testing-library

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


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?


Solution

  • 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).


    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.