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
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');
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 returnnull
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.
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 usequeryBy
APIs instead: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.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 isnull
.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()
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();
});
});
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();
});
Another solution: you could also use a try/catch
block
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();
}