Enzyme Adapter Utilities
The `enzyme-adapter-utils` package (version 1.14.2, last published 2 years ago) serves as a foundational utility layer for developing and maintaining official and third-party Enzyme adapters. It provides common functionalities, abstract classes (like `EnzymeAdapter`), and helper methods necessary for an adapter to bridge Enzyme's API with specific versions of React or other UI component libraries (e.g., Preact, Inferno). Unlike the main `enzyme` package, `enzyme-adapter-utils` is not intended for direct use by application developers writing tests. Its primary consumers are the developers of `enzyme-adapter-react-*` packages. As an internal component of the Enzyme ecosystem, its release cadence is tightly coupled with major Enzyme releases and React compatibility updates. It enables the modularity of Enzyme, allowing it to support multiple React versions simultaneously without requiring a monolithic testing library. This package is crucial for ensuring Enzyme's continued compatibility with the evolving React landscape, although the broader Enzyme ecosystem faces challenges with newer React versions.
Common errors
-
Enzyme Internal Error: Enzyme expects an adapter to be configured, but found none.
cause The Enzyme library has not been configured with a specific adapter for your React version.fixInstall the correct `enzyme-adapter-react-*` package for your React version (e.g., `npm i --save-dev enzyme-adapter-react-16`) and configure Enzyme in your test setup file: `import Enzyme from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; Enzyme.configure({ adapter: new Adapter() });` -
npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree
cause Dependency conflicts, often between your project's React version and the `peerDependencies` of `enzyme-adapter-react-*` or `enzyme-adapter-utils` packages. This is common when upgrading React without updating Enzyme adapters, or with incompatible versions.fixEnsure that your `react` and `react-dom` versions are compatible with the specific `enzyme-adapter-react-*` package you are using. If conflicts persist, try `npm install --force` or `npm install --legacy-peer-deps` (use with caution as it can lead to broken dependencies) or downgrade/upgrade React to match the adapter's requirements. -
Enzyme Internal Error: configured enzyme adapter did not inherit from the EnzymeAdapter base class
cause The adapter provided to `Enzyme.configure()` does not correctly extend the `EnzymeAdapter` class from `enzyme-adapter-utils` or is otherwise malformed. This error is typically encountered when developing a custom adapter or if an existing adapter package is corrupted/incorrect.fixVerify that your custom adapter correctly extends `EnzymeAdapter` or reinstall the official `enzyme-adapter-react-*` package to ensure it's not corrupted. Ensure no conflicting versions of `enzyme-adapter-utils` are present.
Warnings
- breaking Enzyme's major version 3 introduced an adapter system, which fundamentally changed how Enzyme interacts with React versions. This involved significant refactors in internal utility packages like `enzyme-adapter-utils`. Older adapters (v2.x) are incompatible with Enzyme v3.x and require migration.
- breaking Enzyme, and by extension its adapter utilities, has faced significant challenges maintaining compatibility with newer React versions (17, 18, and beyond) due to reliance on React's private internal APIs. There is no official Enzyme adapter for React 18, and the library is largely unmaintained, with its ecosystem frozen. This means `enzyme-adapter-utils` is unlikely to receive updates for future React API changes.
- gotcha `enzyme-adapter-utils` is an internal package used by adapter developers, not directly by application developers. Attempting to import and use its functions or classes directly in application test code is usually an anti-pattern and can lead to unstable tests or unexpected behavior due to internal API changes.
- breaking When using `mount` with React 16.8+ (which introduced Hooks and `act()`), Enzyme automatically wraps relevant APIs (like `.simulate()`, `.setProps()`) with `ReactTestUtils.act()`. However, for other state updates or effects triggered outside these specific APIs, you might need to manually wrap them with `act` (e.g., from `react-test-renderer/test-utils` or `@testing-library/react`) to ensure consistent test behavior and prevent 'act' warnings.
Install
-
npm install enzyme-adapter-utils -
yarn add enzyme-adapter-utils -
pnpm add enzyme-adapter-utils
Imports
- EnzymeAdapter
import { EnzymeAdapter } from 'enzyme-adapter-utils';import EnzymeAdapter from 'enzyme-adapter-utils';
- RSTreeNode
import RSTreeNode from 'enzyme-adapter-utils';
import { RSTreeNode } from 'enzyme-adapter-utils'; - syncWithReactDom
import syncWithReactDom from 'enzyme-adapter-utils';
import { syncWithReactDom } from 'enzyme-adapter-utils';
Quickstart
import EnzymeAdapter, { RSTreeNode, syncWithReactDom } from 'enzyme-adapter-utils';
import { configure } from 'enzyme';
// This is an illustrative example of a custom adapter using enzyme-adapter-utils.
// End-users typically install and configure existing adapters (e.g., enzyme-adapter-react-16).
class CustomEnzymeAdapter extends EnzymeAdapter {
constructor() {
super();
console.log('CustomEnzymeAdapter initialized.');
}
// Required methods for a custom adapter (simplified for example):
createRenderer(options) {
if (options.mode === 'mount') {
syncWithReactDom(); // Example utility usage
}
console.log(`Creating renderer for mode: ${options.mode}`);
return {
render: (node, context) => {
// In a real adapter, this would perform actual rendering
console.log('Rendering node:', node);
// Return a mock RSTreeNode for demonstration
return new RSTreeNode('div', { className: 'rendered' }, [], null);
},
unmount: (node) => console.log('Unmounting node:', node),
getNode: (node) => new RSTreeNode('span', {}, [], null), // Example utility usage
};
}
// Other required adapter methods would be implemented here
isValidElement(element) { return true; }
nodeToElement(node) { return node; }
nodeToHostNode(node) { return null; }
displayNameOfNode(node) { return node.type || 'Unknown'; }
// ... many more methods
}
// To actually use this adapter, you would configure Enzyme with it:
// configure({ adapter: new CustomEnzymeAdapter() });
console.log('This code demonstrates how a custom Enzyme adapter would leverage `enzyme-adapter-utils`.');
console.log('The EnzymeAdapter class, RSTreeNode, and syncWithReactDom are internal utilities for adapter authors.');
console.log('Direct usage by typical test authors is uncommon and not recommended.');