Diogo Souza Brazilian dev. Creator of altaluna.com.br

Getting started with Enzyme for React

7 min read 1964

Getting Started With Enzyme For React

Testing is an important step in web application development, especially when it comes to apps made on top of component libraries like React. Among the many different tools and libraries for testing, Enzyme stands out for its flexibility and its easy-to-develop tests for your React code.

Actually, Enzyme is more of a JavaScript testing utility that makes it easier to assert, manipulate, and traverse your React components’ output. Created by Airbnb, it adds a lot of utility functions to facilitate the component rendering, finding and interacting with elements in a way that feels similar to jQuery.

In this tutorial, we’ll explore the different rendering options the utility provides, along with some practical examples.

Setup and install

First of all, make sure you have Node ≥ v8.10.0 on your local development machine. If you’re not sure whether you’re using the latest version, refer to nvm documentation to confirm.

For this project, we’re going to use create-react-app to set up a React application and get it running in no time. With it, we don’t need to install or configure tools like Webpack or Babel; they are preconfigured and hidden so that we can focus on the code.

It makes use of npx, an npm package runner that comes with npm ≥v5.2, so the whole thing is pretty straightforward. You can read more on npx here. 🙂

So, in order to create our application, run the following command in your prompt:

cd your-project-directory
npx create-react-app logrocket-react-enzyme-app

This will create and initialize the project with a bunch of preset Node modules that are important for React development:

We made a custom demo for .
No really. Click here to check it out.

Facebook create-react-app output.

And this is the generated file and directories structure:

├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│   ├── favicon.ico
│   ├── index.html
│   └── manifest.json
└── src
    ├── App.css
    ├── App.js
    ├── App.test.js
    ├── index.css
    ├── index.js 
    ├── logo.svg
    └── serviceWorker.js

Take a moment to open the package.json file and analyze the pre-installed Node dependencies, including React, React DOM, and scripts; the preset scripts for starting up; building testing; and so on:

  "name": "logrocket-react-enzyme-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-scripts": "3.0.0"
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  "eslintConfig": {
    "extends": "react-app"
  "browserslist": {
    "production": [
      "not dead",
      "not op_mini all"
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"

To check out the running application, just type the npm start command into the application root folder and the index page will be opened in your browser at http://localhost:3000/ just like that:

Index React App page

Now, let’s move on to the Enzyme setup. Once we’re using React 16 (the latest as of writing) for our project development, the following command may be issued to install Enzyme properly:

npm i — save-dev enzyme enzyme-adapter-react-16

After that, you’ll notice that our package.json file was updated:

"devDependencies": {
   "enzyme": "^3.9.0",
   "enzyme-adapter-react-16": "^1.12.1"

If you’re using a different version of React, no worries — you can follow the official Enzyme installation doc for guidance on how to install the right version for your project.

Note: if you’re using Linux and you get the error Error: ENOSPC: System limit for number of file watchers reached, it means your system’s file watchers limit was hit. To fix it, simply run the following command:

echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p

Creating our first test

In order to use Enzyme’s features, we need to tell our React app it is installed and available. However, remember that we need to reference the adapter package we installed earlier and properly set up the adapter to be used by Enzyme. So, go to the src folder and create a new file called enzyme.js:

import Enzyme, { configure, shallow, mount, render } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

configure({ adapter: new Adapter() });
export { shallow, mount, render };
export default Enzyme;

This will be enough to export all the different Enzyme render types. Then, create another folder, tests, into the src/components directory to save our test files.

Let’s consider a simple example: an HTML ordered list. It’ll be composed by two components:

  • OrderedList: this will store the function to build an <ol> of OrderedListOption elements, checking whether the list is empty or not for different display dispositions
  • OrderedListOption: this deals with each <li> item independently, CSS class, and its value

This component could be easily adapted to a <select>, for example, given its list nature. Let’s take a look at the source code:

import React from 'react';
import PropTypes from 'prop-types';

import OrderedListOption from './OrderedListOption';

function OrderedList(props) {
  const { options } = props;
  if (!options.length) {
    return <span className="empty">No options added.</span>;

  return (
    <ol className="options">
      {options.map(option => <OrderedListOption key={option} value={option} />)}

OrderedList.propTypes = {
  options: PropTypes.array,

OrderedList.defaultProps = {
  options: [],

export default OrderedList;

The code is way simple: we’re importing React and the OrderedListOption component at the top of the file while checking for items’ array emptiness for displaying the proper HTML content. If the array is not empty, we’ll iterate over it to compose list options.

Take a look at the OrderedListOption code:

import React from 'react';
import PropTypes from 'prop-types';

function OrderedListOption(props) {
  const { value } = props;
  return <li className="value">{value}</li>;

OrderedListOption.propTypes = {
  value: PropTypes.string,

export default OrderedListOption;

It just receives the value of the element and places it into the <li> element. Simple, isn’t it?

Before we create our tests, it’s important to state the three different render types Enzyme supports.


This basically renders a single component each time. In other words, Enzyme won’t consider the child elements for the test. Consider situations where you’d like to test the component itself isolated from the others around or inside of it. This render type is useful when you prefer unit testing rather than a full integrated test.


This is the opposite of shallow, working with the full DOM rendering, which includes all the child elements. It’s ideal for situations where each component interacts intensively with the others — the DOM API.


It renders to static HTML. This includes all the child elements. At the same time, it prevents access to React lifecycle methods, which, in turn, provides less flexibility and functionalities for testing — besides, it’s much faster. It is built on top of Cheerio, a DOM manipulation and traversal API based on jQuery Core for the server. So, you’ll have all the power of jQuery in your hands.

Now let’s make some tests. Create a new file called OrderedList.test.js in our /tests folder and add the following code:

import React from 'react';
import { shallow, mount, render } from '../../enzyme';

import OrderedList from '../OrderedList';

describe('Our test suite', () => {

    it('renders all the mocked animal options', () => {
        const animals = ['duck', 'bear', 'whale'];

        const wrapper = render(<OrderedList options={animals} />);


    it('renders no animal options', () => {
        const animals = [];
        const wrapper = shallow(<OrderedList options={animals} />);


    it('renders a single animal option', () => {
        const animals = ['duck'];
        const wrapper = mount(<OrderedList options={animals} />);

        expect(wrapper.contains(<li key='duck' className="value">duck</li >)).toBeTruthy();

    it('renders correct text in animal option', () => {
        const animals = ['duck', 'bear', 'whale'];
        const wrapper = mount(<OrderedList options={animals} />);


First, we’re importing the three render types in the beginning of the file from the enzyme.js file we created before. Here, we’re contemplating four test scenarios for each type of rendering.

The first one is for the render type; we’re basically asking Enzyme to render an OrderedList with the given array of animals param and asserting the test conditions through the expect() function.

The wrapper object represents the render() result, and within it, we can call to find the CSS classes options (of our items’ children) and value, regarding each of the inner list elements’ classes. We’re also testing the number of child elements.

The second test focuses on a list that receives no elements. Here, we’re using the shallow render type, which makes methods like exists() available to us.

The last two tests make use of the mount() function, which will return the full DOM to the wrapper object. The method contains() is another example of a React lifecycle method.

Testing form components

You can go even further and test things like forms, form elements, events, and so on. Let’s take a look at a second example, a login form component (Login.js):

import React from 'react';

class Login extends React.Component {
    constructor() {
        this.state = {
            username: '',
            password: ''

    handleInputChange = (event) => {
            [event.target.name]: event.target.value
    render() {
        return (
            <form className='login'>
                <input id='email' onBlur={this.handleInputChange} name='email' type='text' />
                <input id='password' onBlur={this.handleInputChange} name='password' type='password' />
export default Login

It’s a common form structure component, except that the state we’re keeping here must be updated every time a blur event occurs in one of the inputs.

Let’s take a look at the Login.test.js file:

import React from 'react';
import { shallow, mount, render } from '../../enzyme';
import Login from '../Login'

describe('Login Test Suite', () => {

    it('should render the form', () => {
        const wrapper = shallow(<Login />);


describe('Email Test Suite', () => {

    it('should change the state of the Login component', () => {

        const wrapper = shallow(<Login />);
                target: { name: 'email', value: '[email protected]' }

        expect(wrapper.state('email')).toEqual('[email protected]');

describe('Password Test Suite', () => {

    it('should change the state of the Login component', () => {

        const wrapper = mount(<Login />);
                target: { name: 'password', value: 'my log is rocket' }

        expect(wrapper.state('password')).toEqual('my log is rocket');

The first test suite is nothing new; we’re just checking if the form elements exist. The second and third tests are making use of the simulate() function to, as the name suggests, simulate an event in the field — in this case, onBlur.

Once we’ve set that the onBlur will trigger the state update of each input field, we can then check if the same state was stored. That’s a great example of a behavior test, wherein we’re testing what happens after Enzyme forces the simulation of an event in the component.

This would be the final output in your IDE (here, Visual Studio Code):

Test results in the terminal


You can access the full source code from my GitHub repo. If you enjoyed it, please leave a star rating.

We presented here only a few methods and examples among the many others Enzyme provides. It is a dynamic and rich environment for you to create your test suites and explore many different testing scenarios, such as for integration, unitary, behavioral, semantic, and others.

Refer to the official documentation page for more information about Enzyme and its functions, additional configurations, and more. Aim for a well-tested application and make it more trustworthy.

Have you used Enzyme for React? Tell us a bit about the experience…

Full visibility into production React apps

Debugging React applications can be difficult, especially when users experience issues that are hard to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

LogRocket is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — .

Diogo Souza Brazilian dev. Creator of altaluna.com.br

Testing accessibility with Storybook

One big challenge when building a component library is prioritizing accessibility. Accessibility is usually seen as one of those “nice-to-have” features, and unfortunately, we’re...
Laura Carballo
4 min read

Leave a Reply