0

I have Controller:

(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');                
        });
    });
}());

Here is my service: Using $resource making call on getInitialData with getData as custom function.

(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
        };
    }
}());

Wanted to test service call in controller using 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
        });
    });
});

This throws error, service.getInitialData is not function. Any idea why it is throwing error or any other better way to test service call

Tyler.z.yang
  • 2,402
  • 1
  • 18
  • 31
user2323308
  • 759
  • 5
  • 16
  • 34

1 Answers1

1

In Angular, there are some differences between factory and service, check Service vs Factory vs Provider in Angular if you want to know more about it.

One of them is factory return reference Object and service return an Instance

So when you try to define/mock a function or property in factory, you return an Object with property name and value, but in service, you should set it to this.

And beyond of that, you should return a Object which define a function getData so that it can be invoked in your last test case.(Or it will throw undefine is not a function error)

So update your TestMyCtrl into this,

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
        });
    });
});

Hope this can answer your question. : )

Community
  • 1
  • 1
Tyler.z.yang
  • 2,402
  • 1
  • 18
  • 31