GiggleGirl
GiggleGirl

Reputation: 77

Unable to unit test http call happening through the controller

I am trying to write a code to test the service call which is done in my controller . I am trying to unit test that particular function in controller which is doing the service call and bringing the data . Currently i am trying with local json , but it will actually do a service call .

I got to know that first i have to create a spy object but i am getting the error, my goal is to successfully unit test the http call happening in the controller.

i am new to unit testing .Pasting my code , request you to help me please , struggling in this from many days now.Also i have gone through many solutions , they are so different making be confused.Your help is greatly appreciated

Service code :

    //xlpApp is the module name
    xlpApp.factory('xlpServices', ['$rootScope', '$http', function($rootScope, 
    $http) {
    var xlpServices = {};
    xlpServices.getProgramData = function(){
          return $http.get(scripts/services/data/unitTesting.json'); 
     };

unitTesting.json code :

    {
    "name":"unit testing"
    }

Controller Code :

$scope.events = {

    programData: function(){
            xlpServices.getProgramData().then(function(response) {
                if (response && response.data) {
                    $scope.testVariable= response.data.name;
                }
            });
        },
    selectSortingType : function(type) {
            $scope.selectedSorting = type;
            selectedFilter.sortingBy = $scope.selectedSorting;
        }   

}
$scope.events.programData();  

Unit Test Code :

  describe('myProgramGpmCtrl', function() {
  beforeEach(module('xlp'));

  var $controller;

  beforeEach(inject(function(_$controller_){
    $controller = _$controller_;
  }));

describe('service call test', function() {
    var xlpServices , myService , $q;
    var $scope = {};

     beforeEach(inject(function(xlpServices,_$q_){
       xlpServices = xlpServices;
       $q = _$q_;
       var controller = $controller('myProgramGpmCtrl', { $scope: $scope });
       myService = jasmine.createSpyObj('xlpServices',['getProgramData']);
    }));

    it('Service call test ', function() {
      expect(myService.getProgramData).toHaveBeenCalled();
    }); 
});

});

ERROR :

      Expected spy xlpServices.getProgramData to have been called.

Upvotes: 1

Views: 52

Answers (1)

Thaadikkaaran
Thaadikkaaran

Reputation: 5226

Try something like,

describe('service call test', function() {
    var xlpServicesMock , myService , $q;
    var $scope = {};

     beforeEach(inject(function(xlpServices,_$q_){
       xlpServicesMock = xlpServices;
       $q = _$q_;
       spyOn(xlpServicesMock ,'getProgramData').and.callFake(function() {
        // we can return promise instead this custom object  
        return {
            then: (callback, errorCallback) => {
                callback('data to be passed to then callback');
                /* `callback` function should be invoked when you wanted to test the service for success response with status code 200.
                   `errorCallback` function should be invoked with 500 status code when you wanted to test the api failure
                Ex: callback({status: 200, data: <your data here>);
                    errorCallback({status: 500, data: <your error data>})
                You can prepare the response to be passed as you wanted.

                 */

            }
        };
       });

       var controller = $controller('myProgramGpmCtrl', { $scope: $scope, xlpServices: xlpServicesMock  });

    }));

    it('Service call test ', function() {
      $scope.events.programData();
      expect(myService.getProgramData).toHaveBeenCalled();
    }); 
});

There are good resources available online. check here and here

Upvotes: 1

Related Questions