Frontend Development 12 min read

Choosing the Right React Testing Tool: Jest vs Enzyme vs RTL

This article compares React component testing approaches, explains the difference between unit testing and end‑to‑end testing, evaluates popular tools such as Jest, Enzyme, and React Testing Library, and provides practical code examples, snapshot testing tips, and integration with Storybook.

GrowingIO Tech Team
GrowingIO Tech Team
GrowingIO Tech Team
Choosing the Right React Testing Tool: Jest vs Enzyme vs RTL

Preface

GrowingIO Design is a React component library, and like any JavaScript code it can be tested. React component testing methods fall into two categories: rendering a component tree in a simplified environment for assertions (unit testing) and running the full application in a real browser (end‑to‑end testing). This article focuses on unit‑testing strategies.

Tool Research

Based on the 2020 State of JavaScript Survey, tool popularity and satisfaction were compared. Jest and Storybook score high on both metrics, while the newer Testing Library also receives strong satisfaction scores.

Tool Selection

React’s official site (v17.0.2) recommends Jest, which uses jsdom to simulate the DOM, offers fast iteration, and provides powerful mocking capabilities. React Testing Library (RTL) encourages testing without relying on component implementation details and promotes accessibility best practices. Enzyme, once popular, is now less favored because it does not support Hooks out of the box.

Example Component

<code>class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isToggleOn: true };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(state => ({ isToggleOn: !state.isToggleOn }));
  }

  render() {
    return (
      &lt;button onClick={this.handleClick}&gt;
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      &lt;/button&gt;
    );
  }
}
</code>

Enzyme Test

<code>describe("Toggle", () => {
  let component;
  beforeEach(() => {
    component = mount(&lt;Toggle /&gt;);
  });

  it("can turn off when is on", () => {
    component.instance().handleClick();
    expect(component.state().isToggleOn).toEqual(false);
  });

  it("can turn on when is off", () => {
    component.setState({ isToggleOn: false });
    component.instance().handleClick();
    expect(component.state().isToggleOn).toEqual(true);
  });
});
</code>

Testing Library Test

<code>describe("Toggle", () => {
  it("can turn off/on", async () => {
    const { container } = render(&lt;Toggle /&gt;);
    fireEvent.click(container);
    expect(container.innerHTML).toEqual("OFF");
    fireEvent.click(container);
    expect(container.innerHTML).toEqual("ON");
  });
});
</code>

Snapshot Testing

Jest’s snapshot feature captures a serializable representation of a React tree, allowing you to detect unexpected UI changes.

<code>import React from 'react';
import renderer from 'react-test-renderer';
import Link from '../Link.react';

it('renders correctly', () => {
  const tree = renderer
    .create(&lt;Link page="https://www.growingio.com"&gt;GrowingIO&lt;/Link&gt;)
    .toJSON();
  expect(tree).toMatchSnapshot();
});
</code>

Generated snapshot example:

<code>exports[`renders correctly 1`] = `
<a className="normal" href="https://www.growingio.com" onMouseEnter={[Function]} onMouseLeave={[Function]}>
  GrowingIO
</a>
`;
</code>

Storybook Integration

Component demos written for Storybook can be reused in unit tests. Example using RTL:

<code>import React from 'react';
import { render, screen } from '@testing-library/react';
import { Primary } from './Button.stories';

it('renders the button in the primary state', () => {
  render(&lt;Primary {...Primary.args} /&gt;);
  expect(screen.getByRole('button')).toHaveTextContent('Primary');
});
</code>

Conclusion

RTL emphasizes testing from the user’s perspective, making tests more aligned with real‑world usage and accessibility. While Enzyme can achieve similar confidence, its API is less intuitive for modern React features such as Hooks. Adopting RTL, together with snapshot testing and Storybook demos, leads to more maintainable and user‑centric component libraries.

References

GrowingIO Design: https://github.com/growingio/gio-design

State of JavaScript Survey 2020: https://2020.stateofjs.com/zh-Hans/technologies/testing/

React Testing Overview: https://reactjs.org/docs/testing.html

Enzyme: https://enzymejs.github.io/enzyme/

Jest Snapshot Testing: https://jestjs.io/docs/snapshot-testing

Storybook Unit Testing: https://storybook.js.org/docs/react/workflows/unit-testing

ReacttestingStorybookJestEnzymeReact Testing LibrarySnapshot Testing
GrowingIO Tech Team
Written by

GrowingIO Tech Team

The official technical account of GrowingIO, showcasing our tech innovations, experience summaries, and cutting‑edge black‑tech.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.