AngularJS — Jasmine — не удается протестировать службу в функции обратного вызова контроллера

#angularjs #testing #jasmine2.0

#angularjs #тестирование #jasmine2.0

Вопрос:

Мне нужна помощь с тестированием Jasmine. У меня есть этот контроллер с простым сервисом:

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

Тестовый код (работает нормально):

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

Этот тест может только проверить, что вызывается метод InvocationService.get, все в порядке.

Но мне нужно проверить логику функций ‘successCallback’ и ‘errorCallback’ (см. Функцию vm.invocacion_get ()). Эта функция вызывается после вызова ‘InvocationService.get’, но я в этом тесте не вижу никаких изменений. Не имеет значения, имитируются ли данные, возвращаемые службой; идея заключается в том, что переменная ‘vm.idResponse’ изменяет значение.

При поиске в Интернете я видел несколько примеров, но не смог заставить их работать, извините.

Спасибо!

Ответ №1:

Наконец, создайте этот метод тестирования с фиктивными данными и поддельной функцией:

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

Это работает нормально.