React组件测试时Enzyme提示未配置适配器报错如何解决?
问题解决步骤
一、修复Enzyme适配器配置报错
这个报错是因为Enzyme未配置对应React版本的适配器,按以下步骤操作:
- 安装对应版本适配器
- React 16:
npm i enzyme-adapter-react-16 --save-dev - React 17:
npm i enzyme-adapter-react-17 --save-dev - React 18:
npm i @wojtekmaj/enzyme-adapter-react-18 --save-dev(官方适配未发布时用社区兼容版本)
- 配置适配器
两种配置方式二选一即可:
方式1:全局配置(推荐)
在项目src目录下新建setupTests.js文件,添加以下代码:
import Enzyme from 'enzyme'; // 根据你安装的适配器版本引入 import Adapter from 'enzyme-adapter-react-17'; // React18就写 import Adapter from '@wojtekmaj/enzyme-adapter-react-18'; Enzyme.configure({ adapter: new Adapter() });
Jest会自动加载这个文件的配置,所有测试文件都不用重复配置。
方式2:单测试文件配置
直接在你的index.test.js顶部添加上述配置代码即可。
二、修正测试逻辑
你原来的测试存在三个核心问题:
- 给
PropTypesExemple传递的state属性无效,这个值是组件内部的useState状态,不属于接收的props - Enzyme默认无法直接读取函数组件用
useState定义的内部状态,强行调用wrapper.state()会返回空 - 混用了
@testing-library/react和Enzyme两套渲染逻辑,建议统一用一套实现,优先推荐@testing-library/react,它基于用户行为测试,不用关心组件内部状态实现,更符合测试需求
修正后的测试代码(基于@testing-library/react实现,不需要Enzyme)
你完全可以不用Enzyme就实现需求,简化后的index.test.js代码如下:
import { render, screen, fireEvent } from '@testing-library/react'; import { MemoryRouter } from 'react-router-dom'; import PropTypesExemple from './index'; import ChildComponent from './ChildComponent'; describe('Testing the rendering of components', () => { // 测试子组件基础渲染 test('should render child component', () => { render(<ChildComponent />); expect(screen.getByText(/Olá,/)).toBeInTheDocument(); }); // 测试初始状态下子组件不渲染,点击按钮后子组件渲染 test('should render child component after button click', () => { render( <MemoryRouter> <PropTypesExemple /> </MemoryRouter> ); // 初始状态子组件不存在 expect(screen.queryByText(/Olá,/)).not.toBeInTheDocument(); // 触发按钮点击 fireEvent.click(screen.getByText('Me Aperte!!!')); // 点击后子组件渲染,显示默认nome值 expect(screen.getByText('Olá, React App2 !')).toBeInTheDocument(); }); // 扩展测试:输入内容后点击按钮,子组件显示输入的内容 test('should show input value in child component after click', () => { render( <MemoryRouter> <PropTypesExemple /> </MemoryRouter> ); // 输入内容 fireEvent.change(screen.getByRole('textbox'), { target: { value: '测试用户' } }); // 点击按钮 fireEvent.click(screen.getByText('Me Aperte!!!')); // 验证子组件显示输入的内容 expect(screen.getByText('Olá, 测试用户 !')).toBeInTheDocument(); }); });
如果你一定要用Enzyme实现,建议直接测试渲染结果而非内部state值,测试组件对外表现更符合测试原则。
内容的提问来源于stack exchange,提问作者Uriel Libano
相关产品推荐
相关产品推荐

