Testing in React

Uriel Rodriguez
The Startup
Published in
5 min readSep 20, 2020

When learning to program, most people begin using the behavior driven development approach which is writing code to meet a functionality or observable behavior. However, behavior driven development, also referred to as BDD, derived from TDD or test driven development. TDD focuses on units of software, where tests are written for those units to ensure that the units function as they should. In React, these units could be represented by components where tests are written to check that the component behaves in a certain way otherwise failing the unit test.

The importance of testing are plenty. For example, it ensures that changes introduced to an application whether by refactors or new features does not negatively impact the existing application. Implementing testing in React involves utilizing a test runner which is the library that provides the code for testing and also executes the tests. In addition, testing utilities aid TDD by providing simulations of the React application such as mounting of component and inspecting a components data.

By default, React includes the test runner library JEST as an application dependency when running create-react-app. JEST provides the language to write executable tests for the React application. React also uses testing utilities such as Enzyme which allows to write tests using JEST in a manner that simulates actual components and the data these components would be responsible for without actually having to work with them. As mentioned, to get started you don’t need to install the JEST testing library because it comes pre-installed with create-react-app. After that, all that needs to be installed are the following:

npm install --save enzyme react-test-renderer enzyme-adapter-react-16

Here we are installing enzyme, which is the testing utility, react-test-renderer, which is a dependency for enzyme and the enzyme-adapter-react-16 package which allow enzyme to connect to React. With these packages installed, you can begin to explore writing tests. First when testing components, you can create a file that’s named the same as the component file but with the file extension .test.js.

// Main component
src/components/Main/Main.js
// unit test file
src/components/Main/Main.test.js

After this you need to import a few things from enzyme and the enzyme adapter to get things working properly with the React application. So:

import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });

So above you are essentially connecting enzyme to React and configuring it to work with React via the Adapter. Before you begin writing your tests, it’s important to know the sort of things to test. Some suggested applications for unit testing are testing components to see that they render the correct output such as conditional outputs or child components. Things that should not be tested are third party libraries and their complex connections such as an axios HTTP request to an API. With that, you can begin testing like so:

import React from 'react';
import { configure, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Main from './components/Main/Main;'
import SubMain from './components/SubMain/SubMain;'
configure({ adapter: new Adapter() });describe('Main', () => {
it('it should render two SubMain elements', () => {
let wrapper = shallow(<Main />);
expect(wrapper.find(SubMain)).toHaveLength(2);
});
});

Let’s break down what’s happening this time. We import React because we are going to work with the components that will be tested such as Main and SubMain, which are also imported. Next, the shallow function is imported from the enzyme package which allow the rendering of the component that will be tested, in this case Main. In addition, shallow creates a “shallow” wrapper around the component preventing the loading of its subtree such as the component’s child components and the child component’s child components and so on.

After all this, we begin the unit test with the describe function which represents an entire unit test. It takes two arguments, the first being a string that will represent the component being tested. The second argument is a callback function that will contain the actual tests for the component which is carried out by the “it” function which also takes in two arguments. The first argument is a string statement for what the test is looking for, so in this example, ‘Main’ is being tested and ‘it should render two SubMain elements.’ And the second argument is a callback which contains the code that carries out the test. In this example, we first create the shallow representation of the component being tested. The convention for this is creating a variable called wrapper which is assigned to the call to the shallow function, passing in the Main component in the standard JSX notation. You can look at the documentation for enzyme which will provide more detail about this concept of shallow rendering a component. https://enzymejs.github.io/enzyme/docs/api/shallow.html

Next, we use the expect function which is provided by the JEST library, to test some expectation for the shallow representation of the Main component. In this case, when we invoke the find method on wrapper, checking to find the SubMain component as its child component. After that, we not only expect to find a SubMain component but for the result of that find call to produce two SubMain components found via the toHaveLength(2). Another thing to note is that when passing the SubMain component to the find method, we do not use the JSX notation like we did when creating the shallow representation of the Main component.

With all that, you have written a simple test for a component, testing that it does its job in rendering two components. To execute this test, you simply run:

npm test

The JEST and Enzyme documentation provide more information such as different methods for testing different things and utilizing more data such as props and state values. But in general, this is a good place to start in understanding what unit tests are and when and how to implement them. For much information you can check out these links.

--

--

Uriel Rodriguez
The Startup

Flatiron School alumni and Full Stack web developer.