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

嵌套调用api.send时第二个Promise未触发,单元测试校验失败如何解决

问题根因

  • 方法调用不匹配:业务逻辑定义的方法是getItemForm,但测试代码中调用的是itemToForm,调用错误是首要问题
  • 未等待异步执行:Promise回调属于微任务,会在所有同步代码执行完成后才触发,你当前的测试断言是同步执行的,此时第一个then回调还没运行,第二次api.send自然还没有被调用
  • 测试代码存在语法冗余:component.item = let item = {...}是无效语法,多余的let item =会导致运行异常

修复方案

1. 优化业务代码(可选但推荐)

给Promise链加上返回,方便外部追踪异步执行状态,避免嵌套Promise回调丢失上下文:

getItemForm = () => {
  // 返回外层Promise
  return this.api.send('filter', 'get', { lang: 'ES', filter: { id: this.item['id'] } }).then(res1 => {
    this.item = res1['data'][0];
    // 返回内层Promise,形成完整链式结构
    return this.api.send('filter', 'get', { lang: 'EN', filter: { id: this.item['id'] } }).then(res2 => {
      let itemEng = res2['data'][0];
      return itemEng;
    });
  });
};

2. 修正测试代码

用async/await等待异步逻辑全部执行完成后再做断言,同时修正方法调用和语法错误:

// 测试函数添加async关键字支持异步等待
it('should call api.send with res Eng', async () => {
  component.formDef = [{ field_id: 57, field_key: "name1", field_name: 'test1' }];
  let res1 = { data: [{ id: 1, name: 'test1' }, { id: 2, name: 'test1' }] };
  let res2 = { data: [{ id: 1, name: 'test2' }, { id: 2, name: 'test' }] };
  // 修正语法错误,删掉多余的let item声明
  component.item = {id:1, count: 1, data:[{id: 1, tacticas: {95: [135]}}]};

  let spy1 = spyOn(api, 'send').and.returnValues(Promise.resolve(res1), Promise.resolve(res2));

  // 调用正确的业务方法,等待异步逻辑全部执行完成
  await component.getItemForm();

  expect(spy1).toHaveBeenCalled();
  expect(spy1).toHaveBeenCalledTimes(2);
  // 可补充参数校验的断言,保证调用逻辑正确
  expect(spy1).toHaveBeenNthCalledWith(1, 'filter', 'get', { lang: 'ES', filter: { id: 1 } });
  expect(spy1).toHaveBeenNthCalledWith(2, 'filter', 'get', { lang: 'EN', filter: { id: 1 } });
});

如果不想修改业务代码添加Promise返回,也可以在测试中用微任务清空工具(如Jest的flushPromises、Angular测试的flushMicrotasks)配合done回调完成异步等待,效果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 10:21:02