Chris Manciero
Unit testing React with Jest and Enzyme
Unit testing is viewed as a must have for any code being developed but is usually put off until the end of the project life cycle to fulfill a check box that a project manager is asking for.
I am not going to berate you with reasons why your code should have unit tests, if you don't know by now you will find out one day, which I hope is not at 2 in the morning when an untouched component breaks the day a crucial feature needs to be delivered. Just do a search on "why should I write unit tests?" and enjoy being convinced.
If you have already drank the unit test kool-aid and are looking for a simle example on how to create unit test for your React component using Jest and Enzyme, well you have come to the right place.
Over the course of this blog post I will go through:
* Getting started
* Creating components to be unit tested
* Creating unit test for components
* Running tests
* (Added bonus) - View code coverage report for component and how to get to 100%
Getting started
I am going to create a unit test for my component that I built inside a create-react-app project. If you are not familiar with create-react-app you should check it out. It is the best way to start building a new single-page application in React. If you don't feel like running this project on your computer an alternative is to use CodeSandbox, which allows you to create create-react-app projects on the web.
Before we can start writing unit test we need to install some NPM modules to our project. For my unit tests I installed the following modules:
* jest v.23.6.0 (npm i jest)
* enzyme v.3.8.0 (npm i enzyme)
* enzyme-adapter-react-16 v.1.7.1 (npm i enzyme-adapter-react-16)
* react-test-renderer v.16.7.0 (npm i react-test-renderer)
Now that I have the needed NPM modules installed I am ready to create a component to be tested.
Creating components to be unit tested
I am going to start off with a very simple button component that increments the count value on the parent component on every click.

As you can see this button just calls the parent's onClick method on each button click.
Here is the parent component:

Creating unit test for components
Now that our component is working, it's time to create a unit test for it. **Side note: there are developers who live by TDD (Test-Driven Development) approach which would create the test first then the create the component to make the test pass. TDD is another topic for another day.
I am not going to breakdown every little aspect of Jest, I'd rather defer that information to Jest's website (jest.io) where they do a great job explaining how Jest works.
There are different approaches as to where your unit test should reside. One approach is to put the unit test in a .test.js file in a /test directory. For my project I am going to create a .test.js file in the same directory of MyButton component.
File location: /components/MyButton.test.js
In my file I am going to import the npm modules I installed in my project previously as well as the MyButton component that I want to test.

Next, I am going to create my test

You may be asking yourself, "what is this code doing?". Let me explain the code.
On line 9 I have describe("<MyButton Unit Test/>", () => {... this is the start of a describe block. A describe block allows you to group together tests for a component. This is for better troubleshooting when a test fails.
Line 10 contains const defaultButton = <MyButton/>; Here I am using JSX to create the MyButton component and assign it to a variable to be used later in the file.
On line 12 we create our first test. The syntax for creating a test is test(<LABEL TO DEFINE TEST>, TEST FUNCTION)
My test function is creating a snapshot, a DOM render of the MyButton component, to be used each time the unit test is run. Creating a snapshot is a great way to validate if the DOM render has changed because of any properties added or removed.
Currently my snapshot produces this output:
<div> <button onClick={[Function]}> Click Me </button> </div>
Now if I was to add another DOM element in my control (for example a label) the output would change
<div> <label>My new button</label> <button onClick={[Function]}> Click Me </button> </div>
Since I have a snapshot already created for my unit test, this change is found instantly and my unit test fails.

To fix the broken test, I can either update my component (remove the <label>) or update my snapshot.
Now let's test the functionality of the MyButton component. I am going to create a test that
will load the MyButton component and then simulate an onClick event being fired from the component. The test is going to validate that the parent's value for number of clicks is updated correctly after the onClick event is fired.

You can see on line 28 I am making a call to the "shallow" method. This is Enzyme Shallow Rendering API, you can learn about how to use it here. Using the Shallow Rendering API I am able to obtain the <button> DOM element and simulate a click event.
The expect() method calls on line 26, 31 and 39 allows me to check if the value being passed in are what I expecting.
Running Tests
Since this project was created using create-react-app to run test enter the following command
npm test
Here is an example of a successful test

Here is an example of a failed test. You can see that the unit test result points out how the unit test failed and what was the test code that caused the failure.

(Added bonus) - View code coverage report
On top of viewing that your tests have passed, you can also generate a code coverage report on your components to make sure that code written has a test associated with it.
npm test -- --coverage

Running the code coverage check will create a /coverage directory in your project that you can access. In the /coverage/lcov-report directory you can view the index.html file which will allow you to navigate your components and see what lines of code are covered and which lines are not.


Code example
Conclusion
This is just the tip of the iceberg on what you can do with unit testing and how you can quickly and easily see what lines of code are being covered by your unit tests. I suggest you review the documentation from Jest and Enzyme to find out how you can bring your unit testing to the next level.