mcpField
R
react18-enzyme-to-rtl

react18-enzyme-to-rtl

github.com/github测试与质量40.5k740 次安装今天更新
代码仓库

关于 react18-enzyme-to-rtl

面向 React 团队的迁移技能,用 React Testing Library(RTL)重写 Enzyme 测试。它将测试重点从组件内部转向可见行为,并说明 API 与异步模式的对应方式。

主要功能

  1. 01用 RTL 重写 Enzyme 测试
  2. 02测试可见行为而非组件内部
  3. 03映射常见 Enzyme API 至 RTL
  4. 04覆盖异步查询及状态测试
  5. 05优先使用无障碍 RTL 查询

适用场景

  1. 01替换 React 18 代码库中的 Enzyme 测试
  2. 02将状态和实例断言改为界面结果
  3. 03异步测试加载与错误状态

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/github/awesome-copilot --skill react18-enzyme-to-rtl

安装后在 Claude Code 中输入/react18-enzyme-to-rtl确认已加载。

附带文件references/async-patterns.mdreferences/enzyme-api-map.md

详细介绍

React 18 Enzyme → RTL 迁移

Enzyme 没有 React 18 适配器,也没有 React 18 支持路径。所有 Enzyme 测试都必须使用 React Testing Library 重写。

理念转变(请先阅读)

Enzyme 测试实现。RTL 测试行为。

// 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();

这不是 1:1 的转换。验证内部状态或实例方法的 Enzyme 测试没有 RTL 等价物——因为 RTL 有意不暴露内部实现。请重写测试,改为断言可见的结果。

API 对照表

要查看每个 Enzyme API 完整的修改前后代码,请阅读:

  • references/enzyme-api-map.md - 完整映射:shallow、mount、find、simulate、prop、state、instance、configure
  • references/async-patterns.md - waitFor、findBy、act()、Apollo MockedProvider、加载状态、错误状态

核心重写模板

// 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 查询优先级(按此顺序使用)

  1. getByRole - 匹配可访问性角色(button、textbox、heading、checkbox 等)
  2. getByLabelText - 与标签关联的表单字段
  3. getByPlaceholderText - 输入框占位符
  4. getByText - 可见文本内容
  5. getByDisplayValue - input/select/textarea 的当前值
  6. getByAltText - 图片替代文本
  7. getByTitle - title 属性
  8. getByTestId - data-testid 属性(最后手段)

优先使用 getByRole 而不是 getByTestId。它也会测试可访问性。

使用 Provider 进行包裹

// 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

评论

支持 Markdown