How to Test With Jest

Testing React components using Jest and React-Testing-Library.

Caleb
Caleb
Sep 7, 2020 · 9 min read
Photo by Marta Branco from Pexels

Hi there, welcome back! Thank you for stopping by. Last month in my Getting Started with AWS article I wrote:

If you are a budding developer looking to get that first opportunity, it is important to get familiar with some of the different cloud infrastructure providers out there.

The exact same can be said for writing tests for your code and the Testing Frameworks and libraries that help you do it. In this article, we will walk through setting up some unit tests with and for some components in an existing React application.

What is Jest?

Jest is a delightful JavaScript Testing Framework with a focus on simplicity.
It works with projects using: Babel, TypeScript, Node, React, Angular, Vue, and more!

What is React Testing Library?

The is a very light-weight solution for testing React components. It provides light utility functions on top of and , in a way that encourages better testing practices. Its primary guiding principle is:

The more your tests resemble the way your software is used, the more confidence they can give you.

So rather than dealing with instances of rendered React components, your tests will work with actual DOM nodes. The utilities this library provides facilitate querying the DOM in the same way the user would.

Let’s get started!

The Application

For this example, we have a simple SPA bootstrapped using the command. The app has 2 simple components, a counter with “up” and “down” buttons. Clicking them increases and decreases the count displayed on the screen. The other component is a basic form with a submit button. Filling the form and clicking submit will display the message typed in the form.

When you create projects using the command, you have out of the box support for React Testing Library and Jest. If you didn’t use that command, you can add them via like so:

// Install React Testing Library
npm install --save-dev @testing-library/react
// Install Jest
npm install --save -dev jest

The Components:

As mentioned, our first component is the component.

As you can see, it is a very simple component that manages state locally with the hook(line 5 and 6). It has a single arrow function called (line 8) that manages both button clicks with some conditional statements. It also removes the element from the screen based on a nested conditional statements(line 17).

Our second component is the component.

This component has a bit more going on. Again, we manage all our state attributes with the hook(lines 4 – 7). In this case, we have a arrow function (line 9) that manages input changes on the form when the user is typing in the input field. Finally, we have a arrow function (line 13) that triggers all our state changes. Also, this component disables the “Print” button if there is no data in the input field.

The App Test

Since our app was bootstrapped with there is already one test file available for us in the directory of the app called . Let’s break this down a bit.

This is the test file for the component. Notice that like any other React component it starts by importing React (line 1). Then we import the necessary functions from React Testing Library(line 2) followed by importing the component to be tested(line 3).

As the test indicates it is expecting that our App component “renders learn react link” (line 5). To verify this we need to destructure the query and make it equal to the function we imported and we pass it our component(line 6). This basically tells our query where it is going to be looking. Then we create a variable and assign it the return value of the query and pass in the text we are looking for. In the example above, line 7 is passing in a regular expression of the desired text. Now that the query is ready to go the expectation can be set. Here, we expect the text “learn react” to be in the document. This is the basic structure of the tests we will be writing.

// To run tests use these commands// If using yarn
yarn test
// If using npm
npm test

Currently, this test is failing because we changed all the code this was testing for. If you are following along, you should see something like this.

Let’s update our test so we are looking for stuff that actually exists in our document.

Ok, above we have the same test but we added some new variables with a few examples of different ways we are able to search for text. Line 11 shows an example that searches for a string and uses a flag to ignore case sensitivity. Lines 14 and 15 show 2 ways of using regular expressions. Line 15 is looking for a full string match while ignoring case and line 14 is looking for substrings while ignoring case. Now, when we run our test it passes.

The Counter Test

Let’s break down the steps to writing your test from scratch.

1 - Create a test file

Create a new file in the directory with the name of the component to be tested. All test files should follow the same naming convention . In our case, we are testing the component so our file will be called .

2 - Import React, components, and functions

As we did before we go through our imports and this time we also include the function from React Testing Library. This will allow us to simulate button clicks in our tests.

3 - Write functionality tests

With everything in place, we can start writing our test. Since we are already checking that our components render correctly in our file, we can test the functionality of the buttons by testing their individual actions and results.

Testing the “Up” button

In this test, we are making sure that when we click the “Up” button for the first time we get the number 1 printed on the screen. To achieve this, we will be looking at multiple values.

  1. The text on the button.
  2. The text we are looking for as a result of clicking the button.

This means we will need to use a different query function other than . Thankfully, there is a very flexible one called that allows us to search by an id we create on the component we are testing using the attribute.

Then in our test, we can access that id like this.

On line 14 we destructure our query and pass it as an argument to our function and include the we created.

With that test passing, we can pretty much do the same for the “Down” button.

In order to be able to test that the “Down” button decrements the count correctly we have to increment the count first so we added an extra click event on line 26 then we check that the number incremented and then we fire the down click event on line 34.

The Printer Test

Our component has a text input and a submit button. We are going to test a few things here.

1 - Repeat steps 1 and 2 from the previous test.

Create the test file for the component in the directory.
Set all imports.

2 - Start writing tests

We will test a couple of things for each part of this component. We can keep things organized by using Jest’s blocks to group together several related tests.

Input tests

In this example, want to make sure the input field renders. We also so want to test if the input field updates when the user types into it.

We will start with a new describe block.

We’ll group all our input tests inside this block. Our first test will check that the input field renders correctly.

React Testing Library has many queries at our disposal. Here is a very handy cheatsheet. Since we are looking for the text in the component and our component is just the input and buttons we can use the query. Note that this is not the best practice. Normally, we would be using form tags and there would be labels for each input of the form, etc.

A placeholder is not a good substitute for a label so you should generally use instead.

So far all our tests should be passing.

Now we can move on to testing if it updates on change.

As you can see on line 29, we are using a different event called “change”. This allows us to simulate a user inputting text into a form or input field.

Now our describe block should look like this.

And all our tests are passing.

Now we want to make sure that our button works as expected. To do that we need 2 tests, one for each case. The first case is when the button is clicked with some data in the input field. The second case is when there is no data in the input field. To make these tests a bit more descriptive we can wrap each test case in a describe block. This way we are able to state each case individually.

Then we want to add another test inside this describe block to make sure our “Print” button is not disabled when there is data in the input field.

Our “print button” describe block should now look like this. I will remove the notes just so it all fits in the image.

Now, we can add our second case inside its own describe block. Here we want to check that the button is disabled when there is no data in the input field.

This is what our finished “print button” block should look like.

And our tests are all passing!

Just like that, we have written 3 test suites with a total of 8 tests for App and our 2 components. Here is the working app.

I hope this was fun and informative. I’d love to hear your thoughts in the comments. As always, stay healthy, stay curious!

The Startup

Get smarter at building your thing. Join The Startup’s +792K followers.

Sign up for Top 10 Stories

By The Startup

Get smarter at building your thing. Subscribe to receive The Startup's top 10 most read stories — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Caleb

Written by

Caleb

Full-Stack web developer having fun with Rails, JavaScript, HTML, CSS, React, Redux, Bootstrap, Material-UI, and quarantine gardening.

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +792K followers.

Caleb

Written by

Caleb

Full-Stack web developer having fun with Rails, JavaScript, HTML, CSS, React, Redux, Bootstrap, Material-UI, and quarantine gardening.

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +792K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store