【发布时间】:2017-03-11 09:37:02
【问题描述】:
我最近将我的应用程序从 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 中的变化
有人可以解释一下这里可能发生了什么吗?
谢谢
【问题讨论】:
标签: angularjs jasmine angular-promise angularjs-1.6