Testing JavaScript and React With Jest

Cover Image

Testing is a valuable skill in software development. If you take two developers that both have identical skill sets, except one knows how to write tests for their code, that person is always going to stand out. This is because when you have testing in place, you ultimately spend a lot less time and energy on fixing bugs than someone who doesn’t have any tests. You will still have to fix bugs, but you will usually know what class, module, or function is the culprit. Compare this to someone who is in the dark and has to potentially step through many parts of the application to narrow down where the issue is.

In this blog post, I’m going to cover Jest, a framework for testing JavaScript. I will show first how we can use it to test JavaScript code, and then how we can incorporate it into a React project.

Testing JavaScript

To start testing JavaScript, we will need to create a new Node project.

Setup

Open up a terminal in a location where you want to store your code, and run npm init -y to create a new Node project with the default values:

Testing JavaScript 1

Now, open up the project in a code editor and create a new file, stringHelper.js, with the following code:

There isn’t anything too complicated going on here. We have a reverse() method that returns the reverse of a given string and a isPalindrome() method that determines if a string is a palindrome.

Next, let’s install Jest. Open up a terminal in the project location and run:

Installing Jest

This will install Jest and save it as a dev dependency. We do this because we will only ever need Jest in development when testing our code before pushing to production. Once that installs, we need to go into our package.json file and change our test script to be:

Edit package.json 1

 

We can now run npm test in the terminal:

Run Jest 1

It is telling us that no tests were found, which is expected because we haven’t written any yet. This just shows that our script was set up properly.

Testing

To test our StringHelper class, let’s create a corresponding stringHelper.test.js file in our project with the following code:

As you can see, to write a test in Jest, you call the test() method and pass two arguments, a description string of what the test is doing and a callback function. Inside the callback function, we call expect() and pass in what we’re trying to test; in this case, it is our StringHelper methods. We then chain the toBe() “matcher”— Jest uses matchers to test values—onto that and pass in our expected result.

We can now run npm test again and see the results in the terminal:

Run Jest 2

Our tests all passed and this is what the results look like in the terminal. If we wanted to see more detail about our tests, we could edit our test script again:

Edit package.json 2

Now, if we run npm test again we can see a lot more granular detail:

Run Jest 3

Finally, let’s add another file to our project, arrayHelper.js with the following code:

This returns a deep copy of a given array. Again, we need to create an arrayHelper.test.js file to test this:

This looks good so far. But if we rerun npm test, you will see that our test fails:

Run Jest 4

This is basically saying that the two arrays in our test method appear to be equal, but they are not truly equal. Because the original array was deep copied, the new array pointed to a different location in memory. To compare the two arrays by value instead, we need to use the toEqual() matcher:

With that change, our test now passes. And that about wraps up testing JavaScript with Jest. Let’s look at how we can use it with React.

Testing React

If you would like to take a look at the complete source code, you can find it here.

Description

I created a simple app to demonstrate testing in React:

React Demo App 1

Hopefully, we all know where this is from…

So all this app does is start off with an image of Professor Oak and will change based on which Poké Ball is clicked. I made it align with the games, so clicking the middle ball yields Charmander:

React Demo App 2

This is a very simple example, but it is always good to test applications where the user can interact and make changes. This becomes infinitely more important on large scale applications where many people are using it and creating many different scenarios, some of which could cause bugs.

Testing

When we create our React project with Create React App, a setupTests.js file is included:

setupTests.js

The purpose of this file is to import jest-dom, which gives us additional functionality when we go to write our tests. Also, the project includes an App.test.js file already, but in a real world application, it is best practice to create a corresponding test class for each component in the same location as the component.

For example, the component I created for this demo is SelectStarter.jsx:

So to test this, I created a SelectStarter.test.js file:

And both of these reside in a components folder:

Components Folder

In our test code above, we start by calling a describe() method and we pass in our component as the first parameter. You can think of this like we’re describing our component and its expected behavior.

We then pass a callback function containing our test cases (we just have one at the moment). To create a test case, we call the it() method and pass in a string description of what the test is doing as the first parameter, and the second parameter is a callback function containing our actual test code.

In our test code, we call render on the component we’re testing, and we can extract the getByTestId query (there are many other queries that we could use depending on our need—getByText, getByRole, etc.) from that:

getByTestId Query

 

We can give any of our React elements a data-testid attribute. This allows us to grab that element in our test code:

data-testid Usage

Apparently, it is not good practice to overuse getByTestId, but I think it was the best option in this case because the app is made of images so other queries like getByText and getByRole wouldn’t have worked.

In any case, we can run our test by going to the terminal and typing npm run a:

Run Jest With React

It’s passing. Now, let’s add our other tests so SelectStarter.test.js will look like:

We are doing much of the same in our other tests as we did our first test, except now we select our Poké Balls and click them with fireEvent.click(). Before doing so, we still verify that the Professor Oak image is shown, and then after we click we verify that the corresponding Pokémon is selected.

It’s also important to note that while we used the toContain() matcher here, we could have used toEqual() like we did with JavaScript. toContain() made sense here because of how we had to use require() to set our image src attribute.

We can now run npm test a again to see the results:

Run Jest With React

Conclusion

Hopefully, this post has given you a better understanding about how we can use Jest to test JavaScript and React applications. As applications grow in size, testing becomes more important. Whenever we make significant changes across our application and potentially touch many different files and parts of the app, we want to make sure everything still works without having to manually click through the site. We want to have a suite we can run and make sure all of our existing functionality still works as expected.

Thank you for taking the time to read this post and if you have any questions or comments, feel free to reach me via the contact page.