【问题标题】:Mocking angular js service call in controller在控制器中模拟 Angular js 服务调用
【发布时间】:2016-02-16 06:43:15
【问题描述】:

我有控制器:

(function () {
    'use strict';
    angular.module('myApp').controller('myCtrl', function ($scope, myService) {

        // Start -----> Service call: Get Initial Data
        myService.getInitialData().getData(function (featureManagerdata) {
            var serviceData = featureManagerdata;
        }, function (error) {
            showErrorMessage(error, 'getinitialdata');                
        });
    });
}());

这是我的服务:使用 $resource 调用 getInitialData 并将 getData 作为自定义函数。

(function () {
    'use strict';
    angular.module('myApp').factory('myService', ['$resource', myService]);

    function myService($resource) {
        var hostUrl = 'http://x.x.x.x/WebAPIDev';

        function getInitialData() {
            var url = hostUrl + '/featuremanager/allfeatures';
            var options = {
                getData: {
                    method: 'GET',
                    isArray: true
                }
            };
            return $resource(url, {}, options);
        );

        return {
            getInitialData: getInitialData
        };
    }
}());

想要使用 karma-jasmine 在控制器中测试服务调用:

TestMyCtrl:

describe('Test my controller', function() {
    beforeEach(module('myApp'));

    var scope, Ctrl, service;

    angular.module('myApp').service('mockService', function($resource) {
        getInitialData = function() {
            return {
                'featureId': 1
            };
        }
    });

    beforeEach(inject(function(_$controller_, $rootScope, mockService) {
        scope = $rootScope.$new();
        Ctrl = _$controller_('myCtrl', {
            $scope: scope,
            service: mockService
        });
    }));

    it('should test get initial data', function() {
        var response, mockUserResource, $httpBackend, result;

        service.getInitialData().getData(function(data) {
            response = data;
            // verify data
        });
    });
});

这会引发错误,service.getInitialData 不起作用。知道为什么它会抛出错误或任何其他更好的方法来测试服务调用

【问题讨论】:

    标签: javascript angularjs karma-jasmine


    【解决方案1】:

    在 Angular 中,factoryservice 之间存在一些差异,如果您想了解更多信息,请查看 Service vs Factory vs Provider in Angular

    其中之一是 factory 返回引用 Object 和 service 返回一个 Instance

    因此,当您尝试在工厂中定义/模拟一个函数或属性时,您会返回一个带有属性名称和值的Object,但在服务中,您应该将其设置为this

    除此之外,您应该返回一个定义函数getData 的对象,以便可以在最后一个测试用例中调用它。(否则它会抛出 undefine is not a function 错误)

    所以更新你的TestMyCtrl 到这个,

    describe('Test my controller', function() {
        beforeEach(module('myApp'));
    
        var scope, Ctrl, service;
    
        angular.module('myApp').service('mockService', function($resource) {
            //set the function to this.
            this.getInitialData = function() {
                //return {
                //    'featureId': 1
                //};
                //return an object which defined getData function.
    
                return {
                    getData: function(func) {
                        var data = {
                            featureId: 1
                        };
                        //do something here if you want.
                        func(data);
                    }
                };
            }
        });
    
        beforeEach(inject(function(_$controller_, $rootScope, mockService) {
            scope = $rootScope.$new();
            Ctrl = _$controller_('myCtrl', {
                $scope: scope,
                service: mockService
            });
        }));
    
        it('should test get initial data', function() {
            var response, mockUserResource, $httpBackend, result;
    
            service.getInitialData().getData(function(data) {
                response = data;
                // verify data
            });
        });
    });
    

    希望这可以回答您的问题。 :)

    【讨论】:

      猜你喜欢
      • 2015-03-20
      • 2014-11-22
      • 1970-01-01
      • 2014-01-16
      • 1970-01-01
      • 2013-06-24
      • 2015-06-26
      • 2018-07-21
      • 1970-01-01
      相关资源
      最近更新 更多