修改每个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,然后需要将其解析为一个单独的步骤。
原文链接:https://www.f2er.com/angularjs/145208.html在你的情况下,传递给间谍的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'); });