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
相关产品推荐
相关产品推荐

