从Enzyme迁移测试用例至RTL:React 18测试代码改写求助
从Enzyme迁移到RTL:改写findWhere逻辑的方案
改写后的RTL版本代码
import { render, screen } from '@testing-library/react'; function useButtonTests( comp: React.ReactElement, buttonId: string, ) { // 用RTL的render替代Enzyme的shallow,渲染组件到真实DOM render(comp); // 获取所有id匹配的DOM元素,对应原代码的findWhere(node => node.prop('id') === buttonId) const matchingElements = screen.queryAllByAttribute('id', buttonId); let result; if (matchingElements.length > 1) { // 筛选出<button>标签的元素,对应原代码的findWhere(node => node.type() === 'button') const buttons = matchingElements.filter(el => el.tagName === 'BUTTON'); result = expect(buttons); } else { // 只有一个匹配元素时,直接断言该元素 result = expect(matchingElements[0]); } return result; }
关键逻辑转换说明
- 渲染方式替换:RTL核心是模拟用户视角操作真实DOM,因此用
render替代Enzyme的shallow(若需模拟浅渲染,可结合Jest.mock隔离子组件,但多数场景下RTL推荐完整渲染)。 - findWhere替代:
- 原代码通过
findWhere根据id属性查找组件节点,对应RTL的queryAllByAttribute('id', buttonId),直接从DOM中获取所有id匹配的元素。 - 原代码第二次
findWhere筛选button类型节点,对应DOM元素的tagName判断(DOM标签名默认大写,所以用BUTTON),通过数组filter实现筛选。
- 原代码通过
- 类型优化:移除了原代码中的
any类型,改用React.ReactElement作为组件参数类型,更符合TypeScript规范。
更贴合RTL理念的优化方案
RTL推荐用**角色(Role)或测试ID(Test ID)**查询元素,而非依赖业务用的id,如果可以修改组件给按钮添加data-testid属性,可进一步简化代码:
import { render, screen } from '@testing-library/react'; function useButtonTests( comp: React.ReactElement, buttonTestId: string, ) { render(comp); // 直接查找测试ID匹配的按钮元素,一步到位 const buttons = screen.queryAllByRole('button', { testId: buttonTestId }); return expect(buttons); }
内容的提问来源于stack exchange,提问作者Valentine
相关产品推荐
相关产品推荐

