Enzyme
Enzyme is a JavaScript Testing utility for React, designed to simplify the testing of React Components' output by providing methods to manipulate, traverse, and simulate runtime. Its API was influenced by jQuery, offering an intuitive way to interact with component trees. The last stable version released was 3.11.0, published in December 2019. Enzyme required specific 'adapter' packages (e.g., `enzyme-adapter-react-16`) to link with particular React versions. However, Enzyme is no longer actively maintained and has not received official updates or support for React 17, 18, or subsequent versions, due to significant changes in React's internal APIs. While unofficial community-maintained adapters exist for newer React versions, they are not officially supported and may have limitations. The project is effectively abandoned, and the React community has largely shifted towards `React Testing Library` for component testing, which promotes testing from a user's perspective rather than implementation details.
Common errors
-
Enzyme Internal Error: Enzyme expects an adapter to be configured, but found none. To configure an adapter, you should call `Enzyme.configure({ adapter: new Adapter() })` once at the top of your test suite before any tests run.cause The `Enzyme.configure` method was not called, or was called incorrectly, to register a React adapter before tests were executed.fixCreate a test setup file (e.g., `src/setupTests.js` for Create React App) and add: ```javascript import Enzyme from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; // Or the appropriate adapter for your React version Enzyme.configure({ adapter: new Adapter() }); ``` Ensure this setup file is correctly referenced by your test runner (e.g., `jest --config '{"setupFilesAfterEnv": ["<rootDir>/src/setupTests.js"]}''`). -
TypeError: Cannot read properties of undefined (reading 'simulate')
cause Attempting to call `.simulate()` or other wrapper methods on a wrapper that contains no nodes or has not correctly rendered a component.fixVerify that the selector used to find the element (`wrapper.find('button')`) is correct and that the component renders as expected. If using `shallow`, ensure the target element is directly rendered by the component being tested or use `.dive()` if interacting with a child component. Ensure you are not trying to simulate events on a non-interactive element or an element that doesn't exist. -
Invariant Violation: Could not find 'store' in the context of 'Connect(MyComponent)'. Either pass it as a prop to 'Connect(MyComponent)' or wrap it in a <Provider>.
cause Testing a connected (e.g., Redux) component directly with `shallow` or `mount` without providing the necessary context (like a Redux store).fixWhen testing connected components, either shallow render the unconnected component directly, or `mount` the connected component wrapped in a `Provider` with a mock store. For `shallow` tests, use `shallow(<ConnectedComponent store={mockStore} />)` or `shallow(<ConnectedComponent />).dive()` to get to the underlying component if it's connected. -
Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead.
cause Attempting to use an `enzyme-adapter-react-XX` that relies on the deprecated `ReactDOM.render` API with React 18 or newer.fixThis warning indicates Enzyme's fundamental incompatibility with modern React rendering mechanisms. While unofficial adapters like `@cfaester/enzyme-adapter-react-18` attempt to bridge this, they are workarounds. The recommended fix is to migrate tests to `React Testing Library`.
Warnings
- breaking Enzyme is no longer officially maintained and has no official adapters for React versions 17, 18, or 19+. Attempting to use it with these versions without unofficial, community-maintained adapters will fail.
- deprecated Enzyme's philosophy of testing React components by directly accessing internal state and implementation details is now largely considered an anti-pattern. Modern React testing best practices, promoted by `React Testing Library`, focus on testing user-visible behavior.
- gotcha A correct `enzyme-adapter-react-XX` package must be installed and configured for the specific major version of React being used (e.g., `enzyme-adapter-react-16` for React 16). Forgetting this step or using the wrong adapter will result in runtime errors.
- gotcha Enzyme has limited or no reliable support for modern React features like Hooks, Concurrent Mode, and Suspense, especially with unofficial adapters.
Install
-
npm install enzyme -
yarn add enzyme -
pnpm add enzyme
Imports
- shallow
const shallow = require('enzyme').shallow;import { shallow } from 'enzyme'; - mount
const mount = require('enzyme').mount;import { mount } from 'enzyme'; - render
const render = require('enzyme').render;import { render } from 'enzyme'; - configure
require('enzyme').configure({ adapter: new require('enzyme-adapter-react-16')() });import Enzyme, { configure } from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; Enzyme.configure({ adapter: new Adapter() });
Quickstart
import Enzyme, { shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import React from 'react';
// Configure Enzyme with the React 16 adapter
Enzyme.configure({ adapter: new Adapter() });
// A simple React component to test
function MyComponent({ name }) {
return (
<div>
<h1 className="greeting">Hello, {name}!</h1>
<button onClick={() => alert(`Clicked ${name}`)}>Click Me</button>
</div>
);
}
describe('MyComponent', () => {
it('renders a greeting with the correct name', () => {
const wrapper = shallow(<MyComponent name="World" />);
expect(wrapper.find('.greeting').text()).toEqual('Hello, World!');
});
it('simulates click events', () => {
const mockCallBack = jest.fn();
const wrapper = shallow(<MyComponent name="Test" onClick={mockCallBack} />);
wrapper.find('button').simulate('click');
// In a real scenario, mockCallBack would be passed as a prop
// and this test would verify if the prop function was called.
// Here we're just showing the simulate usage.
expect(true).toBe(true); // Placeholder for actual assertion
});
});