Angularjs 迁移到Angular 1.6.3后无法测试被拒绝的承诺
我最近将我的应用程序从Angular 1.5更新到1.6.3,并开始发现Jasmine单元测试失败(使用PhantomJS),原因是我编写的基于承诺的代码: 可能未处理的拒绝:未定义的抛出 环顾四周,我发现公认的解决方案是将.then()与.catch()块链接起来,以优雅地处理拒绝 我已经为我的一个源文件做了这项工作,我正在测试这个源文件,以证明它克服了错误 然而,它现在发现了另一个问题,即当在我的代码中调用承诺拒绝时,我正在测试的期望不再通过 这是我尝试测试的函数(在添加所需的catch块之后) 下面是测试:Angularjs 迁移到Angular 1.6.3后无法测试被拒绝的承诺,angularjs,jasmine,angular-promise,angularjs-1.6,Angularjs,Jasmine,Angular Promise,Angularjs 1.6,我最近将我的应用程序从Angular 1.5更新到1.6.3,并开始发现Jasmine单元测试失败(使用PhantomJS),原因是我编写的基于承诺的代码: 可能未处理的拒绝:未定义的抛出 环顾四周,我发现公认的解决方案是将.then()与.catch()块链接起来,以优雅地处理拒绝 我已经为我的一个源文件做了这项工作,我正在测试这个源文件,以证明它克服了错误 然而,它现在发现了另一个问题,即当在我的代码中调用承诺拒绝时,我正在测试的期望不再通过 这是我尝试测试的函数(在添加所需的catch块之
var thing = {foo: 'bar'},
deferredRemove,
deferredConfirm,
//Mock service below injected into controller later on before test are run
UserMessages = {
buildConfirmDialog: jasmine.createSpy('buildConfirmDialog').and.callFake(function() {
deferredConfirm = $q.defer();
return deferredConfirm.promise.catch(angular.noop);
})
};
//Inject and controller setup here...
describe('When deleting something', function() {
beforeEach(function() {
deferredRemove = $q.defer();
spyOn(someService, 'remove').and.returnValue(deferredRemove.promise.catch(angular.noop));
});
describe('and the user confirms the deletion', function() {
beforeEach(function() {
ctrl.deleteSomething(thing);
deferredConfirm.resolve();
deferredRemove.resolve();
$rootScope.$apply();
});
it('should call remove on someService', function() {
console.log('someService.remove.calls = ' + someService.remove.calls.count());
expect(someService.remove).toHaveBeenCalled();
});
});
describe('and the user cancels the deletion', function() {
beforeEach(function() {
someService.remove.calls.reset();
vm.deleteSomething(thing);
deferredConfirm.reject({});
$rootScope.$apply();
});
it('should not call remove on someService', function() {
console.log('someService.remove.calls = ' + someService.remove.calls.count());
expect(someService.remove.calls.count()).toEqual(0);
});
});
});
在升级到1.6.3之前,我没有安装.catch(angular.noop)
部件,并且遇到一些帖子建议这样做以使测试愉快,这当然有助于我克服测试运行中未处理的拒绝错误
我现在面临的问题是,对于拒绝测试规范,在我的服务中不应该调用remove函数,因此调用的数量应该是零,但它一直是1。我在测试中添加了重置调用的行,以确保它不是前一个测试的结果(我知道调用是在测试之间重置的)
当我在1.5上时,这个测试运行得很好,所以这一定是因为我的代码\测试的编写方式不能很好地处理1.6.x中的更改
有人能解释一下这里可能发生的事情吗
谢谢通过此配置禁用可能未处理的拒绝,然后再次测试
app.config(['$qProvider', function ($qProvider) {
$qProvider.errorOnUnhandledRejections(false);
}]);
通过此配置禁用可能未处理的拒绝,然后再次测试
app.config(['$qProvider', function ($qProvider) {
$qProvider.errorOnUnhandledRejections(false);
}]);
在升级到1.6.3之前,我没有安装.catch(angular.noop)
部件,并且遇到一些帖子建议这样做以使测试愉快,这当然有助于我克服测试运行中未处理的拒绝错误
添加.catch(angular.noop)
肯定会处理未处理的拒绝
它将被拒绝的承诺转换为履行的承诺强>
您的测试正确地失败了,因为您破坏了代码
有关详细信息,请参阅
AngularJS V1.6对$q的更改 报告不拒绝回调的承诺 拒绝的承诺没有回调来处理拒绝报告 这将发送到
$exceptionHandler
,以便将它们记录到控制台
零钱
未处理的拒绝承诺将记录到$exceptionHandler
取决于$exceptionHandler
将需要处理拒绝的承诺报告
将抛出的错误视为常规拒绝
以前,承诺的oncompleted
或onRejected
处理程序中抛出的错误在
与常规拒收略有不同的方式:
它们被传递到$exceptionHandler()
(除了转换为拒绝之外)
这种行为的理由是,未捕获的错误不同于常规的拒绝,正如
例如,它可能是由编程错误引起的。在实践中,这被证明是令人困惑的
或者对用户来说是不受欢迎的,因为本地promises和任何其他流行的promise库都不受欢迎
区分抛出的错误和常规拒绝。
(注意:虽然这种行为不违反法律,但也没有规定。)
此提交通过跳过对$exceptionHandler()
的调用来消除区别,从而
将错误作为常规拒绝抛出
注意:
除非明确关闭,否则可能未处理的拒绝仍将被捕获并传递给
$exceptionHandler()
,因此由于编程错误而引发的错误不会以其他方式处理(使用
后续的onRejected
handler)不会被忽略
有关更多信息,请参见在升级到1.6.3之前,我没有.catch(angular.noop)
部分,并且遇到一些帖子建议这样做以使测试愉快,这当然有助于我克服测试运行中未经处理的拒绝错误
添加.catch(angular.noop)
肯定会处理未处理的拒绝
它将被拒绝的承诺转换为履行的承诺强>
您的测试正确地失败了,因为您破坏了代码
有关详细信息,请参阅
AngularJS V1.6对$q的更改 报告不拒绝回调的承诺 拒绝的承诺没有回调来处理拒绝报告 这将发送到
$exceptionHandler
,以便将它们记录到控制台
零钱
未处理的拒绝承诺将记录到$exceptionHandler
取决于$exceptionHandler
将需要处理拒绝的承诺报告
将抛出的错误视为常规拒绝
以前,承诺的oncompleted
或onRejected
处理程序中抛出的错误在
与常规拒收略有不同的方式:
它们被传递到$exceptionHandler()
(除了转换为拒绝之外)
这种行为的理由是,未捕获的错误不同于常规的拒绝,正如
例如,它可能是由编程错误引起的。在实践中,这被证明是令人困惑的
或者对用户来说是不受欢迎的,因为本机和任何其他流行的