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

React Testing Library点击按钮触发异步请求测试失败问题

问题根因

你的测试跑不通核心是3个问题:

  1. 没有Mock后端请求:测试环境是jsdom,不会真的发起服务端请求,点击过滤按钮后请求一直处于pending状态,拿不到返回值就不会触发setFiltroFormData更新,filtroFormData一直是空对象,满足不了Object.keys(filtroFormData).length > 0的渲染条件,列表自然出不来。
  2. 交互写法有问题:你手动用act()包裹同步的fireEvent操作本身就是多余的(RTL的事件方法默认已经做了act包裹),而且fireEvent.input不会触发受控表单组件的onChange监听,输入框的值根本没有同步到组件状态里;另外你把输入、点击操作都放在同步act块里,没有等待交互触发的状态更新、异步请求的微任务执行。
  3. 等待逻辑不完整:waitFor会一直轮询直到断言通过或者超时,但前提是触发状态更新的异步流程能正常走完,请求都没mock的话等到超时也等不到列表渲染。

修复步骤

1. 先Mock接口请求

把组件里调用的请求方法Mock掉,返回符合业务逻辑的假数据,保证点击过滤后能正常走完请求、更新状态的流程。比如你的请求是从独立服务模块引入的,直接在测试文件顶部Mock:

// 替换成你实际的请求模块路径和方法名
jest.mock('../services/processo', () => ({
  fetchProcessos: jest.fn(() => Promise.resolve({
    // 返回结构和你真实接口保持一致,保证setFiltroFormData拿到的是非空值
    data: {
      list: [],
      total: 0
    }
  }))
}))

2. 用官方推荐的userEvent代替裸fireEvent

userEvent会模拟真实用户的完整交互路径(比如输入会触发focus、keydown、input、change等一系列事件),比只触发单个事件的fireEvent更贴近真实场景,注意所有userEvent操作都是异步的,需要加await,不要手动包act()。

3. 调整等待逻辑

用自带异步等待能力的findBy系列查询代替waitFor包裹getBy,代码更简洁,也能正确捕获异步状态更新。

修复后的测试代码

import userEvent from '@testing-library/user-event';

// 这里放刚才写的接口Mock代码
it('Deve renderizar o processo lista', async () => {
  const user = userEvent.setup();
  const { getByRole, findByText } = render(
    <HelmetProvider>
      <MemoryRouter>
        <ProcessoGerenciamento />
      </MemoryRouter>
    </HelmetProvider>,
  );

  // 输入查询条件
  await user.type(getByRole('textbox', { name: /número do processo/i }), '1');
  // 点击过滤按钮
  await user.click(getByRole('button', { name: /filtrar/i }));

  // 等待列表标题渲染
  const processoTitulo = await findByText('Processos');
  expect(processoTitulo).toBeInTheDocument();
});

额外排查点

  • 如果Mock后还是不通过,检查Mock返回的数据结构是不是和你filtrarProcesso方法里的解析逻辑匹配,比如有没有判断接口返回code、有没有取错返回字段,必须保证setFiltroFormData最终传入的是非空对象,否则列表不会渲染。
  • 确认getByRole('textbox', { name: /número do processo/i })拿到的是正确的输入元素:如果是自定义输入组件,要检查label有没有和input正确关联,否则输入操作会打到错误元素上,表单状态里的查询参数一直是空的。
  • 不要在测试里手动写act()包裹RTL的方法,RTL本身已经处理了act的兼容,手动包裹反而容易因为漏等异步任务导致状态更新不被捕获。

内容的提问来源于stack exchange,提问作者Renan Morais

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:24:22