Tip: Use Bit to reuse components and build faster! Easily organize and use your components to build more apps with your team. Give it a try.

React spinners with Bit: Choose, Play, Install

Writing our first test

Let’s take the simplest component of them all, the TodoListItem component and add test coverage to it.

TodoListItem.jsx

The implementation code for TodoListItem is listed above so that you can relate to it more easily when walking through the test code below.

TodoListItem.test.js

TodoListItem takes 3 props:

item: which is the actual todo item and has three attributes: index , value and done

, and markTodoDone function prop that will be called when a todo is marked as complete

function prop that will be called when a todo is marked as complete removeItem function prop that will be called when a todo is deleted

Let’s start dissecting the test code to understand what is happening there:

The first step would be actually rendering the component and that is what this line does:

const {getByTestId} = render(<TodoListItem item={item} index=

{itemIndex} markTodoDone={markTodoDone}

removeItem={removeItem}/>)

The render method returns an object that has multiple getByXxx helpers to let you select a specific element in the rendered component and evaluate its attributes.

In our case, we are using one such helpers called getByTestId, which is basically a shortcut to [data-testid=<elementId>] If you check our component code, you would see data-testid added to various elements for each testing.

You can use the other selectors as well if you are not willing to add an explicit data attribute for testing. Listing few of the helpers:

getByLabelText: search for the label that matches the given text

search for the label that matches the given text getByPlaceholderText: search for elements by their placeholder attribute

search for elements by their placeholder attribute getByText: search for elements that have given textual content

react-testing-library uses dom-testing-library (by the same author) behind the scenes to offer DOM testing utility functions for easy querying. You should note that for each of the above get helpers, there are matching getAll API that returns all elements instead of just the first one, and query / queryAll that return null / [] instead of throwing an error.

You see that in our test, we use the getByTestId helper to assert if TodoListItem renders item.value correctly.

Firing Events

To fire events like click or change , we should use one of the above selectors to retrieve the element and then use the fireEvent helper to mimic user interaction on the component.

In our example, this piece of code does exactly that…

fireEvent.click(getByTestId('markAsCompleted'))

expect(markTodoDone).toBeCalledWith(itemIndex)

We select the mark-as-completed tick box using its test id and then fire a click event on that. We have passed a mock jest function as prop when rendering the component and asserting if it has been called would be good indication of the interaction wiring!

Testing Form Interaction

Let’s go over TodoFormTest.js code to understand how to test form elements.

TodoForm.jsx

Again the component code is listed above for easy reference. The test for the same is below:

TodoForm.test.js

We will use fireEvent.change to enter value into the new todo input element and then click on the add button.

In this test, we assert that the jest mock callback function is called along with the value that is entered in the input element

If you have read this far, you would have noticed that in all of the tests, we render the actual component with all its children and dependencies and nothing is mocked out. In react testing parlance, we did not do shallow rendering. I do not recommend using shallow testing and you can read through this excellent post to understand more.

Please do browse through the other examples in the repo to know more about what react-testing-library can do. Feel free to comment and ask me anything!