React Testing Fundamentals with RTL

Damla Mutlu
Delivery Hero Tech Hub
6 min readApr 12, 2022

React testing library is recommended by Facebook to simulate user behavior in your test. It includes a complete set of React DOM testing utilities and it is simple. RTL aimed to imitate actual user actions and workflows.

Installation

If you create your project with Create React App, your project has already included React Testing Library. Also, you can add it via npm like :

Understanding of testing

Test is for simulating user behavior and controlling functionality. The main idea is to check your component includes correct elements, your function returns a correct value and if a user takes an action on your page, your page will respond correctly.

Developers should always keep simple their test idea. I want to explain this with the most common and simple sum function.

You have sum function for addition two number.

const sum = (x,y) => x + y ;

Test of sum :

A thinking way should be like:

send input, get return value and compare with an expected value.

Following line for implementing of our function in test suits with two numbers.

const result = sum(5,8);

And the following line is for testing means if our function works correctly, the expectation is the result to be 13.

expect(result).toBe(13);

After running the test, it will get a PASS.

React Component Testing

But as you know, React code doesn’t have just functions. It has also HTML elements and functions for user actions.

There is a simple component to understand component testing.

According to code, the component has two elements which are a <div> and a <button> .

For the initial test, elements should be found.

According to the test code, we have four parts of the test.

First part is test( ‘control of initial values’, () => {} ) ;

  • First parameter for defining your test. It is for giving information about test’s aim.
  • The second parameter is your function which includes test statements.

Second part is render ( <ReactTestingExample /> );

  • Render returns a DocumentFragment of your rendered component. It provides accessibility of your component elements.

Third part is const button = screen.getByRole(‘button’ , {name: ‘Button’});

  • Screen provides methods for querying the rendered elements of the DOM in order to make assertions about their text content, attributes, and more.
  • getByRole is a type of query method to find elements.

More information about queries

Queries are used for finding elements on the page. There are several types of queries that are “get, find, query”.

Single Elements

Multiple Elements

For more information: https://testing-library.com/docs/queries/about

Fourth part is called as assertion expect(button).toBeInTheDocument();

  • Comparison part of your expectations and result.

For more assertion: https://jestjs.io/docs/expect

Note: I prefer Jest as a test runner. Jest is also a JavaScript testing framework designed to ensure the correctness of any JavaScript codebase.

These four parts are the fundamental code base of the test. But we can need more features to use.

According to our code, the button doesn’t have any click action. However, in reality, a user wants to click on it and waits for something to happen. So, I developed the code as below.

With new additions, the code has two user actions. Code expects user input and displays it after a user clicked the button.

User Actions

About testing, every test should define different test suites. It is more understandable and followable.

The second test suit was created for testing of user actions.

Firstly component has been rendered and then elements have been found which have been explained above.

Next step is simulating user action like below.

fireEvent.change(input , {target: {value : ‘learning test fundamentals’}});

  • fireEvent : Convenience methods for firing DOM events. Another approach for simulating user events is userEvent which is more recommended than fireEvent.

For more information: https://testing-library.com/docs/queries/about

It is the definition of which element will be changed and what value is. And then text element and expected value are compared.

Our component display user input on our page nevertheless sometimes we need to display data which is fetched from like database. For fetching data, fetch or Axios is necessary to use. In this case, we need to mock these functions.

The more confusing part of testing is mocking functions. Mocking function aims that simulating of functions’ behavior by using mock data which is defined by us.

Mock

The above component displays a list of todos by fetching data via “https://jsonplaceholder.typicode.com/todos”.

For testing this component, we should mock Axios as below:

First, we will mock Axios with Jest.

jest.mock(‘axios’);

And second, we will give Axios’ get method a mock implementation to resolve.

axios.get.mockImplementationOnce(() => Promise.resolve(mockRespose));

Finally, we expect that get method has been called at least 1 time and with the correct url.

mockRespose represents mock data to use as return value of promise resolve.

For more information: https://jestjs.io/docs/mock-functions

Moreover, Two new statements have been defined.

describe(‘Mock component testing’ , () => {

it(‘control axios called correctly’ , () => {

Describe and it are an alternative way of defining test suites.

‘Describe’ is used for defining main header of the test and ‘it’ ,that is under describe, for defining related tests with the main header.

According to the example, ‘Mock component testing’ is the main header which means the following tests will be for ToDoList component. And ‘should axios be called correctly’ is a test related to ToDoList component.

Running test is the final step. The following command has been called at terminal:

npm test <js file name >

For my code, nmp test mock.test.js has been called and we displayed the test result below.

There are several types of watch.

For example, if we have fail cases we can just display them by pressing ‘f’ or if we have more than one test files, we can run both of them by pressing ‘a’.

Also, we have a detailed report for the failure case. We can display where is the problem, what the expectation is, and what we received.

--

--