【问题标题】:Angularjs mock a function that returns an $http promiseAngularjs 模拟一个返回 $http 承诺的函数
【发布时间】:2015-12-18 06:30:42
【问题描述】:

我有一个 angularjs 应用程序,其中我有一个控制器,它调用一个返回 $http 调用的服务。该应用程序运行良好,但我正在尝试测试控制器并遇到问题。

我的服务:

myApp.factory("MyService", function ($http) {
     var service = {};

     service.save = function (item) {
         return $http.post('../api/Save', item)
             .success(function () {
                 console.log("Saved items on current page");
             })
             .error(function () {
                 console.log("Error saving items on page")
             });
         };
      return service;
});

我的控制器:

myApp.controller("MyCtrl", function ($scope, MyService) {
    $scope.save = function () {
       MyService.save($scope.data)
        .success(function () {
            //do something
        }).error(function () {
            //do something else
        });
    };        
});

该应用完全按预期运行。

我的规格文件:

describe('MyCtrl', function () {
    var myCtrl, mySvc, scope;

    beforeEach(function () {
        module('MyApp');
        module(function ($provide) {
            $provide.service('MyService', function () {
                this.save = function () { };
            });
        });
        inject(function ($injector) {
            mySvc = $injector.get('MyService');
        });
        spyOn(mySvc, 'save').and.callFake(function () {
            return {
                success: function (callback) {
                    callback({ /* something */ });
                },
                error: function (callback) { 
                    callback({/* something else */ }); 
                }
            };
        });
        inject(function ($controller, $rootScope) {
            scope = $rootScope.$new();
            myCtrl = $controller('MyCtrl', { $scope: scope });
        });
    });
    describe('when save button has been hit', function () {
        it('should save', function () {
            scope.save();
            expect(mySvc.save).toHaveBeenCalled();
        });
    });
});

测试给了我一个错误'undefined' is not an object (near '...}).error(function () {...')。如果我从控制器本身中删除 '...}).error(function () {...') 部分,那么测试工作正常,但我不想摆脱该功能。

【问题讨论】:

    标签: javascript angularjs jasmine angular-mock


    【解决方案1】:

    尝试使用返回回调()

       spyOn(mySvc, 'save').and.callFake(function () {
            return {
                success: function (callback) {
                    return callback({ /* something */ });
                },
                error: function (callback) { 
                    return callback({/* something else */ }); 
                }
            };
        });
    

    【讨论】:

    • 我不使用成功/错误风格的承诺。我总是使用 then/catch 语法。您是否尝试过嘲笑它? return { then: function(callback) { return callback(true); } };我看不出有什么不同,但我看不出你的测试有什么问题。
    • 我不确定你的意思。如果我链接响应,我仍然会遇到同样的错误。
    【解决方案2】:

    我得到了一些工作!问题是在我的控制器中,我正在链接响应行为,模拟函数不知道如何处理。我找到的解决方案是在每个案例之后直接返回函数。

     $provide.service('MyService', function () {
           this.save = function () {
                return {
                     success: function (callback) {
                        callback();
                        return this;
                     }, 
                     error: function (callback) {
                        callback();
                        return this;
                     },
                     finally: function (callback) {
                        callback();
                        return this;
                     }
                };
           };
      });
    

    然后将spy改为just:

    spyOn(mySvc, 'save').and.callThrough();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 2015-09-21
      • 1970-01-01
      • 2015-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多