You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从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;
}

关键逻辑转换说明

  1. 渲染方式替换:RTL核心是模拟用户视角操作真实DOM,因此用render替代Enzyme的shallow(若需模拟浅渲染,可结合Jest.mock隔离子组件,但多数场景下RTL推荐完整渲染)。
  2. findWhere替代:
    • 原代码通过findWhere根据id属性查找组件节点,对应RTL的queryAllByAttribute('id', buttonId),直接从DOM中获取所有id匹配的元素。
    • 原代码第二次findWhere筛选button类型节点,对应DOM元素的tagName判断(DOM标签名默认大写,所以用BUTTON),通过数组filter实现筛选。
  3. 类型优化:移除了原代码中的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 12:37:38