Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

https://thesametech.com/snapshot-testing-in-rtl/

What is Enzyme? Why was it important?

Enzyme is a testing library in react that focused on low-level component unit testing and snapshots. Code written around and tested with Enzyme is validated through shallow rendering of components and validation of rendered content through snapshots and inspection, with a minimum amount of external dependencies being rendered.
As a basic example, this tends to mean that a component that uses internationalization, redux, and paragon (our component library), will not touch any of those pieces of code, but rather have all of those libraries mocked out. In the mindset of unit testing:

...

  • Split out all behaviors into hooks that can be independently tested

  • For each of the possible render states of the component

    • take a shallow “snapshot” of the render to validate order and notify on changes.

    • Inspect shallow renders to validate props passed to children, based on hooks and component props.

Why React-Testing-Library is not necessarily a suitable “replacement” for Enzyme

A strong contender in the react testing space is the React Testing Library (@testing-library/react). This library focuses on the mindset of testing components “as the user would interact with them”. This is a powerful testing methodology, but makes it a difficult “replacement” for Enzyme. Specifically, in the capability to mock out libraries for validation.

...

Most of what this means is that reworking a code base from enzyme to react testing library would require a massive overhaul not just in mocking mechanisms, but in what is mocked and how things are tested in general, which would require a massive refactor in those repo’s, and potentially a philosophical disconnect in testing ideologies.

Solution: @openedx/react-unit-test-utils

I have built a library that will act very similarly to Enzyme in key ways that allow persistence of react mocking patterns and snapshots.  This library builds on the react-test-renderer, built into react (through React 18) and proposed by a principal Facebook React Developer:
https://sviat-kuzhelev.medium.com/goodbye-enzyme-future-of-unit-testing-in-react-v-18-10910f034a8b

...

  • Supports the same mocking patterns as enzyme

    • This means it will continue to support nested/react-style components.

  • Allows querying the rendered component (and all children) by

    • findByType (string or component class)

    • findByTestID (previously only available in react-testing-library)

  • Allows checking if a rendered component or child matches an example snippet of jsx.

Usage

In a test file that was using Enzyme, you can replace your enzyme render by replacing a few lines of code

Shallow Rendering

Import

Code Block
// replace
import { shallow } from 'enzyme';
// with 
import { shallow } from '@openedx/react-unit-test-utils';

...

Code Block
jest.mock('@edx/paragon', () => jest
  .requireActual('@openedx/react-unit-test-utils')
  .mockComponents({
    Button: 'Button', // <Button {...props} />
    Form: { // <Form {...props} />
      Group: 'Form.Group', // <Form.Group {...props} />
      Control: 'Form.Control', // <Form.Control {...props} />
    },
  })); 

What this Solution Doesn’t do

refs

Issue

As with enzyme’s shallow renderer, this renderer will not pass refs.

...

If you want to test ref behavior, it is recommended to have a separate test that uses React-Testing-Library (with simple jsdom mocks), which will faithfully forward refs for testing just behavior around the rendered ref.

Deep Render (Component State and Component Prop updates)

Issue

This repo does not reproduce the mount (deep render) functionality from enzyme. It also does not provide access to component state or to updating the component props for testing effects.

...