Table of contents
1.
Introduction
2.
Jest
2.1.
Snapshot Testing
3.
Jest and Enzyme
4.
Installing and configuring
5.
Creating a Test File
6.
Mount, Shallow, Render
7.
Testing
7.1.
Basic Component Rendering
7.2.
Mock Functions
8.
FAQs
9.
Key Takeaways
Last Updated: Mar 27, 2024
Easy

Using Enzyme with Jest

Author Toohina Barua
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

By mimicking jQuery's API for DOM manipulation and traversal, Enzyme's API is meant to be intuitive and flexible. Jest and Enzyme are two separate but complementary testing tools that work well together to provide flexible and creative testing options. Testing React components is much easier and more readable when Jest and Enzyme are used together.
The differences between the two will be briefly discussed.

Jest

Facebook uses Jest, a JavaScript unit testing framework, to test services and React applications. CRA includes Jest and does not require additional installation.

Snapshot Testing

Snapshot testing, which allows you to create a rendered snapshot of a component and compare it to a previously saved snapshot, is also available in Jest. If the two do not match, the test will fail. Snapshots will be saved in an auto-generate __snapshots__ folder alongside the test file that created them. A simple snapshot might look like this:

Source

Jest and Enzyme

  1. Jest and Enzyme are both designed to test React applications; however, Jest can be used with any Javascript app, whereas Enzyme is only for React.
  2. Jest can render components and test with snapshots without Enzyme; Enzyme simply adds more functionality.
  3. Enzyme can be used without Jest, but if Jest is not used, Enzyme must be paired with another test runner.

Installing and configuring

If not using CRA install Jest:

npm install --save-dev jest babel-jest

Install Enzyme:

npm install --save-dev enzyme enzyme-adapter-react-16 enzyme-to-json

Update your package.json :

"jest": {
 "snapshotSerializers": ["enzyme-to-json/serializer"]
}

In comparison to Enzyme's internal component representation, enzyme-to-json provides a better component format for snapshot comparison. When working with snapshots, you can use snapshotSerializers to reduce code duplication. Without the serializer, the enzyme-to-json method must be used every time a component is created in a test. The serializer never uses toJson() because it must be used individually before it can be passed to Jest's snapshot matcher.

expect(toJson(rawRenderedComponent)).toMatchSnapshot();

With this additional line in package.json it allows you to pass a component created by Enzyme to the Jest .toMatchSnapshot() without calling this interim JSON method.
Create a setupTests.js file at ./src/setupTests.js:

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

If you don't want to use CRA, add this line in the same location as snapshotSerializers above:

"setupFiles": ["./src/setupTests.js"],

Creating a Test File

Jest will search for tests in the following locations:

  • __tests__ folders contain files with the.js suffix.
  • .test.js files are those that have a.test.js suffix.
  • .spec.js files are those that have a.spec.js suffix.

Each test file should be placed next to the code it is testing. This makes sense in terms of semantics, and it also means that relative paths are shorter (./MyComponent vs../../MyComponent, and so on).
This file, MyComponent.test.js, is an example of this:

import React from 'react';
import { shallow } from 'enzyme';
import MyComponent from './MyComponent';
describe('MyComponent', () => {
 it('should render correctly in "debug" mode', () => {
   const component = shallow(<MyComponent debug />);

   expect(component).toMatchSnapshot();
 });
});

When you run npm test in CRA, it will run all of the test files and print the results to the terminal. Using the -- --testPathPattern filename/ and -- --testPathIgnorePatterns filename/customization flags, you can run against specific files only or ignore specific files.

Mount, Shallow, Render

import { mount, shallow, render } from ‘enzyme';

In order to have a component to test one of the above must be used, as in the example further above.

Mounting:

  • Rendering of the entire DOM, including child components.
  • Ideal for use cases where you need to fully test a component that interacts with the DOM API or uses React lifecycle methods.
  • To prevent tests from interfering with one another, unmount() should be called after each test.
  • Allows access to props passed directly to the root component (including default props) as well as props passed to child components.

Shallow:

  • Only the single component is rendered, not its children. This is useful for separating the component from the rest of the system during unit testing. It guards against a child component's changes or bugs affecting the behaviour or output of the component under test.
  • Shallow components have access to lifecycle methods by default as of Enzyme 3.
  • Cannot access props passed into the root component (and thus default props), but can test the effect of props passed into the root component. You're testing what MyComponent renders, not the element you passed into shallow, as with shallow(<MyComponent />).

Render:

  • Including children, renders to static HTML.
  • React lifecycle methods are not accessible.
  • It's less expensive than a mount, but it's less functional.

Testing

Basic Component Rendering

For non-interactive, simple components:

it('should render correctly with no props', () => {
 const component = shallow(<MyComponent/>);

 expect(component).toMatchSnapshot();
});
it('should render banner text correctly with given strings', () => {
 const strings = ['one', 'two'];
 const component = shallow(<MyComponent list={strings} />);
 expect(component).toMatchSnapshot();
});
Events
There are several ways to simulate events or user interactions using the Enzyme API. If you want to test interacting with a child component, you can use the mount method.
it('should be possible to activate button with Spacebar', () => {
 const component = mount(<MyComponent />);
 component
   .find('button#my-button-one')
   .simulate('keydown', { keyCode: 32 });
 expect(component).toMatchSnapshot();
 component.unmount();
});

Mock Functions

You might just want to double-check that a function passed as props was called successfully.

const clickFn = jest.fn();
describe('MyComponent', () => {
 it('button click should hide component', () => {
   const component = shallow(<MyComponent onClick={clickFn} />);
   component
     .find('button#my-button-two')
     .simulate('click');
   expect(clickFn).toHaveBeenCalled();
 });
});

You might want to mock a function imported and used within MyComponent.js, set its return value, check that it is called, and compare its snapshot as things get more complicated.
Let's say we import {SaveToStorage} from'save-to-storage' before creating a new SaveToStorage object with both TryGetValue and TrySetValue methods in MyComponent.js. The default return value of TryGetValue is false; if it returns true, the component will change. These are used by our component in various button clicks.
We can mock this with jest.mock, and we can provide overrides for the functions within it with jest.fn.

const mockTryGetValue = jest.fn(() => false);
const mockTrySetValue = jest.fn();

jest.mock('save-to-storage', () => ({  
 SaveToStorage: jest.fn().mockImplementation(() => ({
   tryGetValue: mockTryGetValue,
   trySetValue: mockTrySetValue,
 })),
}));
describe('MyComponent', () => {
 it('should set storage on save button click', () => {
   mockTryGetValue.mockReturnValueOnce(true);
   const component = mount(<MyComponent />);
   component.find('button#my-button-three').simulate('click');
   expect(mockTryGetValue).toHaveBeenCalled();
   expect(component).toMatchSnapshot();
   component.unmount();  
 });   
});

FAQs

  1. What is the full form of CRA?
    The full form of CRA is Create React App and it is a command that can be used to create react app like so:
    npx create-react-app my-app
  2. What does enzyme-to-json do?
    In comparison to Enzyme's internal component representation, enzyme-to-json provides a better component format for snapshot comparison.
  3. What are snapshotSerializers used for?
    When working with snapshots, you can use snapshotSerializers to reduce code duplication.
  4. Is Jest and React testing library same?
    Jest combines fast iteration with powerful features such as mocking modules and timers to give you more control over how your code runs. The React Testing Library is a collection of helpers that enable you to test React components without having to worry about their implementation details.
  5. What is Jest spyOn?
    jest. spyOn allows you to mock the entire module or individual functions within it. It can be used to track method calls in its most basic form: Note that the above example is a condensed/modified version of the official Jest documentation.

Key Takeaways

In this article, we have extensively discussed using Enzyme with Jest.
We hope that this blog has helped you enhance your knowledge regarding Enzyme with Jest and if you would like to learn more, check out our articles on Coding Ninjas Studio. Do upvote our blog to help other ninjas grow. Happy Coding!

Live masterclass