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

Angular Karma-Jasmine测试:Spec未等待.then块完成就执行断言

问题根源与解决方案

核心问题:服务实现未等待所有异步操作完成

你的initializeAPI函数虽然用await等待了fetch请求完成,但没有等待data.json().then(...)里的异步解析和赋值操作。data.json()返回的是Promise,直接用.then()的话,这些回调会进入微任务队列,在initializeAPI函数执行完毕后才会触发。这就导致测试中await service.initializeAPI()只等了fetch完成,却没等后续的数据解析和赋值,所以断言时数据还未更新。


方案1:修复服务代码(推荐)

将.then()替换为await,让initializeAPI函数真正等待所有异步步骤完成:

async initializeAPI() {
  // 第一个API请求
  let data = await fetch('//my 1st api call');
  const r1 = await data.json();
  console.log("then1");
  this.CLASSDATA = r1.res.rows;
  console.log("API read_classdata called");

  // 第二个API请求
  data = await fetch('//my 2nd api call');
  const r2 = await data.json();
  console.log("then2");
  this.RABILITYDATA = r2.res.rows;

  // 第三个API请求
  data = await fetch('//my 3rd api call');
  const r3 = await data.json();
  this.PABILITYDATA = r3.res.rows;   
  console.log("then3", r3.res.rows[0], this.PABILITYDATA[0]);
  console.log("API read_abilitydata called");
}

修改后,initializeAPI会等待所有JSON解析和数据赋值完成再返回,测试中await service.initializeAPI()之后就能直接拿到正确的数据,原测试用例的断言会自动通过。


方案2:不修改服务,调整测试用例

如果暂时无法修改服务代码,可以通过fakeAsync+flushMicrotasks()强制等待所有微任务(即.then()里的回调)执行完毕:

it('should initialize apis for class and ability', fakeAsync(() => {
  service.CLASSDATA = [];
  const fetchspy = spyOn(window, 'fetch').and.returnValues(
    Promise.resolve(classres), 
    Promise.resolve(rabres), 
    Promise.resolve(pabres)
  );
  initspy.and.callThrough();
  
  // 调用初始化函数
  service.initializeAPI();
  // 刷新所有微任务队列,触发所有.then()回调
  flushMicrotasks();

  expect(fetchspy).toHaveBeenCalledTimes(3);
  expect(service.CLASSDATA).toEqual(MOCKCLASSDATA);
}));

这种方式能绕过服务的异步缺陷,但仅适合临时测试场景,长期来看还是修复服务代码更可靠——实际业务中也需要确保所有数据加载完成后再执行后续逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 08:40:23