AngularJS - Jasmine - Cannot test Service in Controller callback function

68 Views Asked by At

I need help with Jasmine test. I have this controller with a simple service:

angular.module('${project.name}')
  .controller('MyControllerCtrl', function ($scope, InvocationService) {
    $scope.vm = {};
    var vm = $scope.vm; 
    vm.idResponse="";
    
    vm.invocacion_get = function(){
        var successCallback = function (response){
               vm.idResponse = response.data.totalElements;
               //More complex logic here that must tested, but no....
        }

        var errorCallback = function(error){
            vm.idResponse = error;
        }   
        
        var url = "prefernces/details?id=1";
        InvocationService.get(url, successCallback, errorCallback);
    } 
})

.factory('InvocationService', function($q) {
  var factory = {};           
  factory.get = function(url,successCallback, errorCallback) {
       var deferred = $q.defer();              
       var allData = $http.get("/risam-backend/rest/"+url).then(successCallback, errorCallback)
       deferred.resolve(allData);
       return deferred.promise;
     }
    return factory;
  });

The test code is (work fine):

describe('Testing a controller', function() {
      var $scope, ctrl;
      var serviceMock;
      
      beforeEach(function (){
        serviceMock = jasmine.createSpyObj('InvocationService', ['get']);
        module('${project.name}');          

        inject(function($rootScope, $controller, $q, _$timeout_) {
          $scope = $rootScope.$new();
          ctrl = $controller('MyControllerCtrl', {
            $scope: $scope,
            InvocationService : serviceMock        
          });
        });
      });

      it('test method vm.invocacion_get()', function (){
        $scope.vm.invocacion_get();
        expect(serviceMock.get).toHaveBeenCalled(); //This work ok
      });
    });

Whit this test only can check that metod InvocationService.get is called, it's ok.

But I need test the logic of functions 'successCallback' and 'errorCallback' (See vm.invocacion_get() function). This functions is called after 'InvocationService.get' is invoqued, but i this test cannot see anything change. It does not matter if the data returned by the service is simulated; the idea is that the variable 'vm.idResponse' changes value.

Searching the web I saw some examples but couldn't get them to work, sorry.

Thanks!

1

There are 1 best solutions below

0
Carlos Mazzoli On

Finally, create this test method with mock data and fake function:

  it('test method vm.invocacion_get() with call fake function', function (){
    
    serviceMock.get.and.callFake(function (){
        var data = {"totalElements":23};    //Mock data 
        var response = [];
        response.data = data; 
    
        var url = arguments[0]; // 'arguments', it´s the magic
        var successCallback = arguments[1];
        var errorCallback = arguments[2];
        return successCallback(response);   //I choose 'successCallback' function in this case
    });
    
    $scope.vm.invocacion_get();
    expect(serviceMock.get).toHaveBeenCalled(); //This work ok
    expect($scope.vm.idResponse).toEqual(23);; //This work ok. 23 is value expected in this variable. It was set by 'successCallback' function
    
  });

This work ok.