返回promise的单元测试服务Angularjs Jasmine

前端之家收集整理的这篇文章主要介绍了返回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');
});

如果你不想将函数的内部工作暴露给它的调用者,你通常会这样做。这类似于在同步编程中重新抛出异常的概念。

原文链接:https://www.f2er.com/angularjs/145208.html

猜你在找的Angularjs相关文章