Testing React’s code with Jest and Enzyme

Today’s topic is different from anything I’ve ever blogged about. Today’s topic is essential to any software engineer looking for a job or looking to become better at coding.

At every interview, I was asked how do you debug your code. I gave so many answers such as a debugger, chrome tools, developer tools, ext. For every job requirement, there was a requirement that I didn’t pay enough attention to, a testing framework.

Today’s blog is more exciting and helpful to React developers looking for better organization, more maintainable code, and fewer bugs.

Note: Keep reading this blog if you have basic Javascript and React knowledge.

Before diving deeper into talking about Jest and Enzyme, I’d like to explain the reasons why I decide to take this class and blog about it.

I am a passionate Javascript developer who is a Bootcamp grad from a software engineering school where I built many React projects. Still, sometimes I struggle when I find bugs that get me demotivated, that I end up spending countless hours debugging. This was when I decided to learn how to write testing files using Jest.

Now let’s talk about how we can use Jest to test our code. I already mentioned the TDD technique:

  • Write a test. Which we will write soon.
  • Make sure the test fails, so you make sure the test is working.
  • Write code.
  • Make sure the test passes.

First you create an app using npx create-react-app click-counter-for-blog . Npm already provide us with the Jest framework, so simply let’s do a quick test using npm test

Screenshot of a terminal after running npm test

Now, if we give a command of a which runs all tests.

Screenshot of a terminal after running npm test a

If you wonder where this test comes from, you’ll find your answer in the first line. src/App.test.js thanks to create-react-app.

Now let’s take a look at App.test.js

Screenshot of App.test.js

Let’s now talk about our Application’s wireframe which will be simple. One component that will look like this

Screenshot of localhost:3000 of basic React Component

Before learning Jest, I would dive in and write code and test my code based on bugs and errors. But now I get to write tests, so I don’t even have to look at the browser. Let’s download some dependencies that will be helpful to write our tests.

  • We need Enzyme, a JavaScript Testing utility for React that makes it easier to assert, manipulate, and traverse your React Components’ output. Enzyme’s API is meant to be intuitive and flexible by mimicking jQuery’s API for DOM manipulation and traversal. In short words, “ Enzyme creates a virtual dom for testing.”

npm i --save-dev enzyme jest-enzyme enzyme-adapter-react-17

Those three dependencies will allow us to create a virtual dom to test without even running npm start without a browser.

Note: If you hit an error installing or importing enzyme-adapter, try the following code:

npm i — save-dev @woktekmaj/enzyme-adapter-react-17

Now let’s get to work!!

At first, we need to import Enzyme, EnzymeAdapter and get rid of the testing library from React.

Second, we need to configure Enzyme’s Adapter by adding an object with a keyword adapter and a new instance of EnzymeAdapter.

Now let’s write our first test using the Shallow method to render the single component that we are testing. It does not render child components. In Enzyme version less than 3, the shallow method cannot access lifecycle methods.

Shallow is known as a wrapper which we will be stored in a variable.

test("render without crashing", () => {
const wrapper = shallow(<App />)
)}

One thing I like to do before coding is to ask myself what I will build in this project and what state and props I have in my components, and then I start writing tests. For this counter-example, I need tests such as:

  • Test to check if app “renders without error.”
  • Test to check if app “renders increment button.”
  • Test to check if app “renders counter display.”
  • Test to check if “counter display starts at 0”.
  • Test to check if “clicking button increment counter variable.”
Screenshot of all tests before writing them

Now something to consider, since we are using Shallow on the component as a wrapper, we will just get the first child. We need to be more specific to get any element in the component. This is when the data-test attribute comes in handy!

Screenshot to explain why use data-set

Enzyme uses the shallow to search for particular values within the shallow wrapper. Please look at the Enzyme-docs to learn more about the fantastic variety of methods you can use to test elements.

Right now we will use the .find(selector) => attribute syntax which will be our data-test. So if we have a div with an attribute like this:

<div data-test="component-app" />

In our test we would look for it this way:

test("render without crashing", () => {
const wrapper = shallow(<App />)
const appComponent = wrapper.find("[data-test='component-app']") expect(appComponent.length).toBe(1)
)}

Adding the expect() method will test our component. If we don’t have a component with that data-attribute “data-test=component-app”, our test will fail. Try it yourself!

If this clicks with you, we have to define that wrapper in every test, use shallow.find method to get the data-attribute we assign for each element, then check using one of the methods to see if the value is the same as expected.

If we run our tests, we will fail the second and the third tests, which we need to see. Now we have to go to App.js and add those elements with the data-attributes we assigned.

You can defiantly make your code more DRY by building a function that takes the wrapper and the data-attribute and pass that function for every test, but for the purpose of not making this blog too long, I’ll skip explaining that part.

Now let’s create a state using the useState hook by importing useState and assign it to zero.

const [count, setcount] = useState(0)

Now how do we check if our function is working correctly to increase the count state by 1?

  • Find the button using the wrapper.find method with the data-attr.
  • Check if the button was clicked, using the button.simulate(‘click’) method.
  • Find the display, and test that the number was incremented by checking the old state and the new state.

And then add the incrementCount function at the App component.

And all our tests pass!!

I hope that was helpful and informative!

Mokhtar

Web Developer | World Traveler | Positive Attitude

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