New to Claude Skills? Learn how to install them →

github on GitHub

React 18 Enzyme to RTL Migration

OfficialFree

Effortlessly transition Enzyme tests to React Testing Library.

by github37.7k stars on github/awesome-copilot
3 views
Updated Aug 10, 2026
Get this skill

Free · Opens the source repo

What React 18 Enzyme to RTL Migration does

The React 18 Enzyme to RTL Migration skill provides a structured approach for developers looking to rewrite their Enzyme tests for React 18 compatibility. Since Enzyme does not offer support for React 18, this skill is essential for any team needing to transition their testing framework to React Testing Library (RTL). It emphasizes the fundamental shift in testing philosophy from implementation-focused tests to behavior-driven tests, ensuring that tests reflect user interactions and outcomes rather than internal states.

This skill includes a comprehensive API mapping that outlines how to convert various Enzyme methods to their RTL equivalents. Developers will find detailed examples for common Enzyme functions such as shallow, mount, wrapper.find(), and wrapper.simulate(), providing clear before-and-after code snippets. The skill also covers best practices for querying and asserting in RTL, prioritizing accessible queries to improve the overall quality of tests.

In addition to the API mapping, users will benefit from guidelines on how to wrap components with providers, which is crucial for testing components that rely on context or external data sources. The skill encourages developers to adopt a testing strategy that aligns with RTL's philosophy, promoting tests that are more resilient and reflective of real user experiences.

This skill is particularly useful for teams migrating legacy codebases or those who want to future-proof their testing strategies in light of React's evolution. By following the provided templates and guidelines, developers can ensure a smoother transition to RTL, ultimately leading to more maintainable and effective tests.

When to use it

Use this skill when you need to rewrite existing Enzyme tests to work with React 18 and RTL.

When not to use it

This skill is not suitable for projects that do not use Enzyme or for teams not transitioning to React Testing Library.

What you can build with it

Migrating a Legacy Codebase

A team with a large codebase of Enzyme tests can use this skill to systematically convert their tests to RTL, ensuring compatibility with React 18.

Improving Test Resilience

Developers looking to enhance their test suite can leverage this skill to adopt RTL's behavior-driven approach, resulting in more robust tests.

Training New Team Members

This skill serves as a valuable resource for onboarding new developers who need to understand the differences between Enzyme and RTL.

How to install React 18 Enzyme to RTL Migration

View source

1. Install with the skills CLI

npx skills add github/awesome-copilot/react18-enzyme-to-rtl --agent claude-code

2. Or install it manually

Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.

Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs

Inside SKILL.md

Written by github

React 18 Enzyme → RTL Migration

Enzyme has no React 18 adapter and no React 18 support path. All Enzyme tests must be rewritten using React Testing Library.

The Philosophy Shift (Read This First)

Enzyme tests implementation. RTL tests behavior.

// Enzyme: tests that the component has the right internal state
expect(wrapper.state('count')).toBe(3);
expect(wrapper.instance().handleClick).toBeDefined();
expect(wrapper.find('Button').prop('disabled')).toBe(true);

// RTL: tests what the user actually sees and can do
expect(screen.getByText('Count: 3')).toBeInTheDocument();
expect(screen.getByRole('button', { name: /submit/i })).toBeDisabled();

This is not a 1:1 translation. Enzyme tests that verify internal state or instance methods don't have RTL equivalents - because RTL intentionally doesn't expose internals. Rewrite the test to assert the visible outcome instead.

API Map

For complete before/after code for each Enzyme API, read:

  • references/enzyme-api-map.md - full mapping: shallow, mount, find, simulate, prop, state, instance, configure
  • references/async-patterns.md - waitFor, findBy, act(), Apollo MockedProvider, loading states, error states

Core Rewrite Template

// Every Enzyme test rewrites to this shape:
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import MyComponent from './MyComponent';

describe('MyComponent', () => {
  it('does the thing', async () => {
    // 1. Render (replaces shallow/mount)
    render(<MyComponent prop="value" />);

    // 2. Query (replaces wrapper.find())
    const button = screen.getByRole('button', { name: /submit/i });

    // 3. Interact (replaces simulate())
    await userEvent.setup().click(button);

    // 4. Assert on visible output (replaces wrapper.state() / wrapper.prop())
    expect(screen.getByText('Submitted!')).toBeInTheDocument();
  });
});

RTL Query Priority (use in this order)

  1. getByRole - matches accessible roles (button, textbox, heading, checkbox, etc.)
  2. getByLabelText - form fields linked to labels
  3. getByPlaceholderText - input placeholders
  4. getByText - visible text content
  5. getByDisplayValue - current value of input/select/textarea
  6. getByAltText - image alt text
  7. getByTitle - title attribute
  8. getByTestId - data-testid attribute (last resort)

Prefer getByRole over getByTestId. It tests accessibility too.

Wrapping with Providers

// Enzyme with context:
const wrapper = mount(
  <ApolloProvider client={client}>
    <ThemeProvider theme={theme}>
      <MyComponent />
    </ThemeProvider>
  </ApolloProvider>
);

// RTL equivalent (use your project's customRender or wrap inline):
import { render } from '@testing-library/react';
render(
  <MockedProvider mocks={mocks} addTypename={false}>
    <ThemeProvider theme={theme}>
      <MyComponent />
    </ThemeProvider>
  </MockedProvider>
);
// Or use the project's customRender helper if it wraps providers

Frequently asked questions about React 18 Enzyme to RTL Migration

Similar skills