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

Jasmine单元测试编写Promise拒绝场景用例时出现Unhandled promise rejection错误的排查求助

解决Jasmine测试中未处理的Promise拒绝问题

我帮你排查了几个导致Unhandled promise rejection错误的核心问题,咱们一步步来修复:

1. 移除async函数与Q Defer的冲突

你的测试用例里,callFake用了async关键字,但又手动返回了Q的deferred promise。async函数会自动把返回值包装成原生Promise,这会和Q的Promise产生兼容性冲突,导致拒绝状态没有被正确捕获。

把async去掉,直接返回Q的promise即可:

spyOn(utility, 'getInfo').and.callFake(() => { 
  var deferred = q.defer(); 
  deferred.reject({ error: 500 }); 
  return deferred.promise; 
});

2. 修正Promise链的错误处理逻辑

你原来的promise.then().catch(...)写法有隐患:如果promise意外被resolve,空的then方法会让后续错误无法被捕获。更稳妥的方式是直接监听catch,同时确保断言完成后正确调用done,还要捕获断言失败的错误:

let promise = utility.someFunction(a,b,c); 
expect(utility.getInfo).toHaveBeenCalled(); 

promise.catch(function (data: any) {
  expect(data).toEqual({ error: 500 });
  done();
}).catch(done); // 把断言失败的错误传递给Jasmine,避免测试挂起

或者更推荐使用Jasmine的expectAsync语法(无需手动管理done),让测试代码更简洁可靠:

it('should reject when getInfo request fails', async () => { 
  spyOn(utility, 'getInfo').and.callFake(() => { 
    var deferred = q.defer(); 
    deferred.reject({ error: 500 }); 
    return deferred.promise; 
  }); 

  // 直接断言Promise被拒绝并匹配错误内容
  await expectAsync(utility.someFunction(a, b, c)).toBeRejectedWith({ error: 500 });
  expect(utility.getInfo).toHaveBeenCalled(); 
});

3. 优化原函数的Promise写法(可选但推荐)

你的someFunction手动创建了deferred对象,这其实是不必要的。按照Promise最佳实践,我们可以直接返回getInfo的Promise链,避免手动管理defer状态,减少出错概率:

someFunction(a,b,c) { 
  return this.getInfo(b,c).then((data)=> { 
    // do Something 
    return data; // 直接返回处理后的数据,自动触发resolve
  }); 
  // 如果getInfo失败,会自动传递拒绝状态,无需手动调用reject
}

额外检查:确保Spy的this指向正确

确认someFunction中的this.getInfo确实指向utility.getInfo。如果someFunction是类的方法,可能需要在测试时绑定this(比如utility.someFunction.bind(utility)),不过从你的代码来看,直接调用utility.someFunction()应该没问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 14:37:38