1

I have some experience in frontend projects using testing-library, but definitely I'm not an expert. During the code review process on most of those projects, it was really common to find some test suites with this structure:

// Original code: https://github.com/callstack/react-native-testing-library/blob/0ede61780bd8788dfa09572643a14c9988c7b92b/examples/reactnavigation/src/__tests__/AppNavigator.test.js#L24

test('clicking on one item takes you to the details screen', async () => {
    const component = (
      <NavigationContainer>
        <AppNavigator />
      </NavigationContainer>
    );

    const { findByText } = render(component);
    const toClick = await findByText('Item number 5');

    fireEvent(toClick, 'press');

    // ---------------- is this neccessary? --------------------

    const newHeader = await findByText('Showing details for 5');
    const newBody = await findByText('the number you have chosen is 5');

    expect(newHeader).toBeTruthy(); 
    expect(newBody).toBeTruthy();

    // ---------------------------------------------------------

});

My doubt is if we are not ending up being redundant with this approach to check if an element does exists on DOM...

According to the docs, if we use getBy or findBy, it should throw an error when there is no matches. So I assume that there's no way for a getBy returns a falsy value, or a findBy resolves a falsy value. And if it is true, so maybe we don't need to check it again. Does it make sense?

So I was wondering if it would be really bad if we just do like this:

test('clicking on one item takes you to the details screen', async () => {
    const component = (
      <NavigationContainer>
        <AppNavigator />
      </NavigationContainer>
    );

    const { findByText } = render(component);
    const toClick = await findByText('Item number 5');

    fireEvent(toClick, 'press');

    await findByText('Showing details for 5');
    await findByText('the number you have chosen is 5');
});

Idk if it makes sense but afaik check if those calls didn't throw error should be enough to validate if an element exists on DOM, is that right?

  • 1
    Yes, that would be enough in that case. However, for consistency and readability, I find it's better to have explicit assertions (in the form of `expect` statements). – juliomalves Oct 25 '21 at 18:13

1 Answers1

1

Tossing in the expectations communicates the intent of the test better, even if you're correct that they're not strictly necessary. I don't see any apparent performance penalty to including them, either.

You may prefer to use queryByText which will return an element or null and let you write "normal" expects that are called on both success and failure cases. However, query doesn't wait for the predicate as find does, so you could use waitFor to build your own find. See About Queries for details on the differences.

If you expect an element queried by text not to exist, I've found that this can trigger large component object tree diffs that can slow down testing considerably (and serializing circular structures can crash it). You might use expect(!!queryByText("this shouldn't exist")).toBe(false); to avoid this scenario by converting the found element to a boolean.

ggorlen
  • 44,755
  • 7
  • 76
  • 106