How do you test for the non-existence of an element using jest and react-testing-library?

ReactjsJestjsReact Testing-Library

Reactjs Problem Overview


I have a component library that I'm writing unit tests for using Jest and react-testing-library. Based on certain props or events I want to verify that certain elements aren't being rendered.

getByText, getByTestId, etc throw and error in react-testing-library if the element isn't found causing the test to fail before the expect function fires.

How do you test for something not existing in jest using react-testing-library?

Reactjs Solutions


Solution 1 - Reactjs

From DOM Testing-library Docs - Appearance and Disappearance

> ## Asserting elements are not present > > The standard getBy methods throw an error when they can't find an element, so > if you want to make an assertion that an element is not present in the DOM, > you can use queryBy APIs instead: > > javascript > const submitButton = screen.queryByText('submit') > expect(submitButton).toBeNull() // it doesn't exist > > > The queryAll APIs version return an array of matching nodes. The length of the > array can be useful for assertions after elements are added or removed from the > DOM. > > javascript > const submitButtons = screen.queryAllByText('submit') > expect(submitButtons).toHaveLength(2) // expect 2 elements > > > ### not.toBeInTheDocument > > The jest-dom utility library provides the > .toBeInTheDocument() matcher, which can be used to assert that an element is > in the body of the document, or not. This can be more meaningful than asserting > a query result is null. > > javascript > import '@testing-library/jest-dom/extend-expect' > // use `queryBy` to avoid throwing an error with `getBy` > const submitButton = screen.queryByText('submit') > expect(submitButton).not.toBeInTheDocument() >

Solution 2 - Reactjs

Use queryBy / queryAllBy.

As you say, getBy* and getAllBy* throw an error if nothing is found.

However, the equivalent methods queryBy* and queryAllBy* instead return null or []:

> 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). > > queryAllBy > queryAllBy* queries return an array of all matching nodes for a query, and return an empty array ([]) if no elements match.

https://testing-library.com/docs/dom-testing-library/api-queries#queryby

So for the specific two you mentioned, you'd instead use queryByText and queryByTestId, but these work for all queries, not just those two.

Solution 3 - Reactjs

getBy* throws an error when not finding an elements, so you can check for that

expect(() => getByText('your text')).toThrow('Unable to find an element');

Solution 4 - Reactjs

You have to use queryByTestId instead of getByTestId.

Here a code example where i want to test if the component with "car" id isn't existing.

 describe('And there is no car', () => {
  it('Should not display car mark', () => {
    const props = {
      ...defaultProps,
      base: null,
    }
    const { queryByTestId } = render(
      <IntlProvider locale="fr" messages={fr}>
        <CarContainer{...props} />
      </IntlProvider>,
    );
    expect(queryByTestId(/car/)).toBeNull();
  });
});

Solution 5 - Reactjs

const submitButton = screen.queryByText('submit')
expect(submitButton).toBeNull() // it doesn't exist

expect(submitButton).not.toBeNull() // it exist

Solution 6 - Reactjs

Worked out for me (if you want to use getByTestId):

expect(() => getByTestId('time-label')).toThrow()

Solution 7 - Reactjs

Another solution: you could also use a try/catch block

expect.assertions(1)
try {
    // if the element is found, the following expect will fail the test
    expect(getByTestId('your-test-id')).not.toBeVisible();
} catch (error) {
    // otherwise, the expect will throw, and the following expect will pass the test
    expect(true).toBeTruthy();
}

Solution 8 - Reactjs

You can use react-native-testing-library "getAllByType" and then check to see if the component is null. Has the advantage of not having to set TestID, also should work with third party components

 it('should contain Customer component', () => {
    const component = render(<Details/>);
    const customerComponent = component.getAllByType(Customer);
    expect(customerComponent).not.toBeNull();
  });

Solution 9 - Reactjs

I recently wrote a method to check visibility of element for a jest cucumber project.

Hope it is useful.

public async checknotVisibility(page:Page,location:string) :Promise<void> 
{
    const element = await page.waitForSelector(location);
    expect(element).not.toBe(location);	
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSomethingOnView Question on Stackoverflow
Solution 1 - ReactjskentcdoddsView Answer on Stackoverflow
Solution 2 - ReactjsSamView Answer on Stackoverflow
Solution 3 - ReactjsGabriel VasileView Answer on Stackoverflow
Solution 4 - ReactjsValentin GarreauView Answer on Stackoverflow
Solution 5 - ReactjsDHIRENDRA SINGHView Answer on Stackoverflow
Solution 6 - Reactjsmatrixb0ssView Answer on Stackoverflow
Solution 7 - ReactjsBassemView Answer on Stackoverflow
Solution 8 - ReactjsAndy RichView Answer on Stackoverflow
Solution 9 - ReactjsMetacoderView Answer on Stackoverflow