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

Angular 17链式Promise单元测试失败,如何修复?

Angular 17链式Promise单元测试修复方案

问题原因

测试断言失败是因为原生Response对象的json()方法返回的Promise未被Zone.js的fakeAsync环境正确跟踪,导致flush()/tick()无法触发后续的then回调;另外代码中Promise.resolve(mockItem.promise)属于多余嵌套,可简化。

解决方案

方案一:模拟Response对象,确保Promise被Zone.js跟踪

修改测试代码,手动模拟Response的json()方法,返回受控的Promise:

it(`nested promise testing`, fakeAsync(() => {
  let item = '';
  // 模拟Response对象,自定义json方法返回可被Zone跟踪的Promise
  const mockResponse = {
    json: () => Promise.resolve({ foo: 'bar' })
  } as unknown as Response;

  const mockItem = {
    promise: Promise.resolve(mockResponse),
  };  

  mockItem.promise
    .then((response) => response.json())
    .then((data) => {
      item = data.foo;
    });

  flushMicrotasks(); // 精准处理所有待执行的微任务
  expect(item).toEqual('bar');
}));

方案二:改用async/await测试语法

直接使用async/await替代fakeAsync,让测试自动等待异步操作完成:

it(`nested promise testing`, async () => {
  let item = '';
  const mockItem = {
    promise: Promise.resolve(new Response(JSON.stringify({ foo: 'bar' }))),
  };  

  await mockItem.promise
    .then((response) => response.json())
    .then((data) => {
      item = data.foo;
    });

  expect(item).toEqual('bar');
});

说明

  • 方案一通过模拟原生对象,避免了测试环境对浏览器API的依赖,确保Zone.js能正确捕获异步任务;flushMicrotasks()专门处理微任务,比flush()更贴合Promise场景。
  • 方案二的async/await语法更直观,无需手动管理任务队列,适合大多数异步测试场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 06:55:16