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

Jest嵌套Promise中断言无返回,报零断言调用错误求助

解决Jest中嵌套Promise断言未被识别的问题

我完全懂你遇到的这个困扰——明明嵌套Promise里的断言语法在其他场景能跑,但到了Jest里就报错“Expected one assertion to be called but received zero assertion calls.”,核心原因其实是Jest没有正确追踪到嵌套Promise的完成状态,导致它在断言执行前就提前结束了测试。

问题根源

Jest判断异步测试是否完成的逻辑很明确:要么测试函数返回一个Promise,要么你调用done回调,要么用async/await语法。如果你的嵌套Promise没有被正确链式返回,外层的then会默认返回undefined(不是Promise),Jest就会误以为测试已经完成,而内层的Promise此时还在异步执行,断言自然没机会被触发。

举个典型的错误写法:

test('实时API测试', () => {
  fetch('/first-endpoint')
    .then(res => res.json())
    .then(data => {
      // 这里没有return内层Promise,Jest看不到它
      fetch('/second-endpoint')
        .then(res => res.json())
        .then(result => {
          expect(result).toEqual('预期值');
        });
    });
});

三种解决方案

1. 正确链式返回Promise

把内层的Promise通过return传递出去,让整个测试函数返回完整的Promise链,Jest就会一直等待到整个链执行完毕:

test('实时API测试', () => {
  // return整个Promise链
  return fetch('/first-endpoint')
    .then(res => res.json())
    .then(data => {
      // return内层Promise,延续链式调用
      return fetch('/second-endpoint')
        .then(res => res.json())
        .then(result => {
          expect(result).toEqual('预期值');
        });
    });
});

2. 用async/await简化(最推荐)

嵌套Promise用async/await改写会更清晰,也能彻底避免链式返回的遗漏问题,Jest会自动等待所有await操作完成:

test('实时API测试', async () => {
  // 第一步请求
  const firstRes = await fetch('/first-endpoint');
  const firstData = await firstRes.json();

  // 第二步请求(基于第一步结果的话也能直接用)
  const secondRes = await fetch('/second-endpoint');
  const secondData = await secondRes.json();

  // 断言会在所有异步操作完成后执行
  expect(secondData).toEqual('预期值');
});

3. 使用done回调(兼容老写法)

如果一定要保留嵌套Promise的写法,可以用Jest提供的done参数,在最后一个断言执行后调用done(),明确告诉Jest测试结束。注意要处理错误分支,不然会导致测试超时:

test('实时API测试', (done) => {
  fetch('/first-endpoint')
    .then(res => res.json())
    .then(data => {
      fetch('/second-endpoint')
        .then(res => res.json())
        .then(result => {
          expect(result).toEqual('预期值');
          done(); // 必须调用done标记测试完成
        })
        .catch(err => done(err)); // 错误时也要调用done,避免超时
    })
    .catch(err => done(err));
});

为什么其他场景能正常运行?

可能那些场景的运行环境(比如浏览器、Node.js脚本)会自动追踪所有异步任务的完成,但Jest作为测试框架,为了保证测试的可靠性,要求必须显式告知它异步操作的边界——毕竟测试需要明确知道什么时候该结束,不能无限等待。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:44:52