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

如何使用Jest测试含Promise逻辑的React函数组件行为

问题原因

测试执行失败的核心原因是异步逻辑的执行时机问题:aPromiseReturningFunction返回的Promise的then回调属于微任务,会在当前所有同步代码执行完毕后才会运行。你在触发click事件后立刻同步执行断言,此时then回调里的setState还未调用,组件state没有更新,渲染内容依旧是初始值12,因此断言不通过。

另外补充一个小问题:你的组件名myComponent首字母为小写,不符合React组件命名规范,React会将首字母小写的标签识别为原生DOM元素,可能引发额外的渲染或测试异常,建议修改为首字母大写的MyComponent。

解决方案

只需要调整测试代码,等待所有异步微任务执行完成,再执行断言即可,以下是两种常用实现方案:

方案1:直接等待微任务队列清空(无需额外依赖)

将测试函数改为异步函数,触发点击后await一个空的Promise,即可让所有已排队的微任务执行完毕,再调用update方法刷新shallow渲染的组件内容,再做断言:

test('点击后等待Promise resolve更新state', async () => {
  const myFunc = jest.fn(() => Promise.resolve(true));
  const componentWrapper = shallow(<MyComponent aPromiseReturningFunction={myFunc} />);
  
  componentWrapper.simulate('click');
  // 等待所有微任务执行完成
  await Promise.resolve();
  // 刷新shallow组件的渲染结果,同步最新state
  componentWrapper.update();
  
  expect(componentWrapper.text()).toEqual('123');
});

方案2:搭配React官方的act工具(更符合测试规范)

使用React测试工具提供的act包裹所有会触发组件更新的操作,确保所有状态更新都完整应用到组件上,再做断言:

import { act } from 'react-dom/test-utils';

test('点击后等待Promise resolve更新state', async () => {
  const myFunc = jest.fn(() => Promise.resolve(true));
  let componentWrapper;
  
  await act(async () => {
    componentWrapper = shallow(<MyComponent aPromiseReturningFunction={myFunc} />);
    componentWrapper.simulate('click');
  });
  
  componentWrapper.update();
  expect(componentWrapper.text()).toEqual('123');
});

如果你的测试开启了Jest的模拟定时器,还需要额外调用jest.runAllTicks()或者jest.useRealTimers()配合使用,默认配置下上述两种方案都可以直接运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 05:24:03