返回promise的单元测试服务Angularjs Jasmine
|
修改每个Michal Charemza职位。
我有一个代表angularui模态对话的服务: app.factory("dialogFactory",function($modal,$window,$q) {
function confirmDeleteDialog() {
var modalInstance = $modal.open({
templateUrl: "../application/factories/confirmDeleteDialog.htm",controller: function($scope,$modalInstance) {
$scope.ok = function() {
$modalInstance.close("true");
};
$scope.cancel = function() {
$modalInstance.dismiss("false");
};
}
});
return modalInstance.result.then(function(response) {
return 'My other success result';
},function(response) {
return $q.reject('My other failure reason');
});
};
return {
confirmDeleteDialog: confirmDeleteDialog
};
});
如果用户从对话框requestNotificationChannel.deleteMessage(id)中单击了Ok,则调用delete方法。 $scope.deleteMessage = function(id) {
var result = dialogFactory.confirmDeleteDialog();
result.then(function(response) {
requestNotificationChannel.deleteMessage(id);
});
};
问题是我不能单元测试这个。 这是我的测试。我已经正确注入q服务,但我不知道应该从“confirmDeleteDialog”间谍… describe("has a delete method that should call delete message notification",function() {
var deferred = $q.defer();
spyOn(dialogFactory,"confirmDeleteDialog").and.returnValue(deferred.promise);
spyOn(requestNotificationChannel,"deleteMessage");
$scope.deleteMessage(5);
deferred.resolve();
it("delete message notification is called",function() {
expect(requestNotificationChannel.deleteMessage).toHaveBeenCalled();
});
});
但我收到预期的间谍deleteMessage已被调用。这意味着result.then …部分不被执行。我缺少什么?
要模拟返回promise的函数,它将需要返回一个promise,然后需要将其解析为一个单独的步骤。
在你的情况下,传递给间谍的deferred.resolve()需要替换为deferred.promise,而deferred.resolve()单独执行。 beforeEach(function() {
var deferred = $q.defer();
spyOn(dialogFactory,"confirmDeleteDialog").and.returnValue(deferred.promise);
spyOn(requestNotificationChannel,"deleteMessage");
$scope.deleteMessage(5);
deferred.resolve();
$rootScope.$digest();
});
it("delete message notification is called",function() {
expect(requestNotificationChannel.deleteMessage).toHaveBeenCalled();
});
我怀疑你还需要调用$ rootScope。$ digest(),因为Angular的promise实现是绑定到摘要循环。 此外,与您的问题稍微不相关,但我不认为你需要在confirmDeleteDialog中创建自己的延迟对象。你使用的(反)模式已标记为“被遗忘的承诺”,如http://taoofcode.net/promise-anti-patterns/ 当更简单,使用更少的代码,我认为允许更好的错误处理,你可以只是返回$ modal服务创建的承诺: var modalInstance = $modal.open({...});
return modalInstance.result;
如果要修改调用函数看到的值,就解析/拒绝值而言,您可以通过返回以下结果来创建链接promise: var modalInstance = $modal.open({...});
return modalInstance.result.then(function(successResult) {
return 'My other success result';
},function(failureReason) {
return $q.reject('My other failure reason');
});
如果你不想将函数的内部工作暴露给它的调用者,你通常会这样做。这类似于在同步编程中重新抛出异常的概念。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
