我最近将我的应用程序从 Angular 1.5 更新到 1.6.3 并开始围绕我编写的基于 Promise 的代码获取 Jasmine 单元测试失败(使用 PhantomJS):
可能未处理的拒绝:未定义抛出
环顾四周,我发现公认的解决方案是将 .then() 与 .catch() 块链接起来,以优雅地处理拒绝。
我已经为我正在测试的一个源文件执行了此操作,以证明这可以解决它所犯的错误。
但是,它现在发现了一个进一步的问题,即当我的代码中调用 promise 拒绝时,我正在测试的期望不再通过。
这是我要测试的功能(在添加所需的 catch 块之后)
public deleteSomething = (thing) => {
return this.UserMessages.buildConfirmDialog().then(() => {
this.someService.remove(thing)
.then(() => {
this.UserMessages.showToast('Something deleted');
})
.catch((error) => {
//handle error
});
})
.catch((error) => {
//handle error
});
}
这是测试:
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)
部件,并且遇到了一些建议这样做以使测试满意的帖子,这肯定有助于我克服测试运行中未处理的拒绝错误。
我现在面临的问题是,对于拒绝测试规范,我的服务中不应该调用删除函数,因此调用次数应该为零,但它一直显示为 1。我添加了该行重置我的测试中的调用以确保它不是以前的测试贡献(我知道调用是为了在测试之间重置)。
当我在 1.5 上时,这个测试运行得很好,所以这一定是我的代码\测试的编写方式不能很好地适应 1.6.x 中的变化
有人可以解释一下这里可能发生的事情吗?
谢谢