Getting started with React Testing Library for unit testing

Introduction

Render API is the one of the important and frequently used API of React Testing library. Once you properly understand what options can be passed to render api and how to use the rendered component to test, it will be easier for you to write the unit test cases.

Output of the render component

The render component returns a object that contains

  • a html container that you are use to run DOM queries like querySelector
  • a wrapper which allows you to run queries as shown below on the baseElement
import { render } from '@testing-library/react';
const wrapper  = render(<Sample/>);

console.log(wrapper.container); // contains the html of Sample component

You can run following queries on the wrapper component

query api

This api is used to query the elements on the DOM. If These apis consists of two sets

queryAllBy

This function queries on the baseElement (document body by default or container if passed), and it returns an array of all matching nodes for a query, and return an empty array ([]) if no elements match.
This is useful when you want to assert that there are no elements.

<div>Test</div>
<div>Test</div>

> wrapper.queryAllByText('Test')
> Array [ <div> Test </div>, <div> Test </div>, ]

queryBy

This function queries on the baseElement (document body by default or container if passed), and it returns the first matching node for a query, and return null if no elements match.
This is useful when you want to assert that there are no elements.

<div>Test</div>
> wrapper.queryByText('Test')
> <div> Test </div>

It throws error if more than one element is found.

<div>Test</div>
<div>Test</div>
> wrapper.queryByText('Test')
> Error: Found multiple elements with the text: Test

get api

There are two apis again

getAllBy

This function queries on the baseElement (document body by default or container if passed), and it returns an array of all matching nodes for a query, and throws error if no elements match.

<div>
Hello World
</div>

When element exist, it will return array of results

wrapper.getAllByText('Hello World').length
> 1

When element does not exist, it will throw error

wrapper.getAllByText('Hello World 2')
>  Unable to find an element with the text: Hello World 2 ....

getBy

This function queries on the baseElement (document body by default or container if passed), and it returns the first matching node for a query, and throws error if no elements match or more than one element match.

<div>
Hello World
</div>

When elem exist, it will return first node

wrapper.getByText('Hello World').textContent
> Hello World

When elem does not exist, it will throw error

wrapper.getByText('Hello World 2').textContent
> Unable to find an element with the text: Hello World 2 ...

When multiple elements are found, it will throw error

Found multiple elements with the text: ...

find api

There are two apis again

findAllBy

This function queries on the baseElement (document body by default or container if passed), and it resolves an array of all matching nodes for a query, and rejects if no elements match. It has default timeout of 1000ms.
It is useful when you want to wait for more than one element (usually a list) to be populated.

<div>Test</div>
<div>Test</div>

Below code waits for one or more Test element to be available.

asyc () => {
  await wrapper.findAllByText('Test')
}

findBy

This function queries on the `baseElement` (document body by default or container if passed), and it returns a promise which resolves matching nodes for a query, and rejects if no elements match.
It is useful when you want to make sure that only one matcher element is found. Used when you want to wait for a progressbar to show up.

<div>Test</div>

Below code waits for one or more Test element to be available.

asyc () => {
  await wrapper.findByText('Test')
}