2014-11-27 2 views
0

Я пытаюсь построить макет службы, чтобы мои модульные тесты могли проверять, что определенные функции вызываются и соответственно обновляются. К сожалению, я не могу заставить это работать.Отказывание тестового модуля HTTP с помощью AngularJS и Jasmine

Im в настоящее время получаю ошибку undefined is not a function на этой линии:

spyOn(statusService, 'getModuleStatus').andCallThrough(); 

Моя текущая служба выглядит следующим образом:

serviceStatusServices.factory('serviceStatusAppAPIservice', function ($http) { 

    var serviceStatusAppAPI = {}; 

    serviceStatusAppAPI.getModuleStatus = function() { 
     return $http({ 
      method: 'JSON', 
      url: '/settings/getservicestatusandconfiguration' 
     }); 
    } 

    serviceStatusAppAPI.setModuleStatus = function (module) { 
     return $http({ 
      method: 'POST', 
      url: '/settings/setservicestatusandconfiguration', 
      data: { moduleId: module.ModuleId, configData: module.ConfigValues } 
     }); 
    } 

    return serviceStatusAppAPI; 
}); 

Моя функция обновления

serviceStatusControllers.controller('serviceStatusController', ['$scope', 'serviceStatusAppAPIservice', '$filter', '$timeout', function ($scope, serviceStatusAppAPIservice, $filter, $timeout) { 

    $scope.update = function() { 
     $scope.loading = true; 
     serviceStatusAppAPIservice.getModuleStatus().then(function (response) { 

      $scope.modules = $filter('orderBy')(response.data.moduleData, 'ModuleName') 
      ... 

Мои тесты выглядеть следующим образом

describe('ServiceStatusController', function() { 
    beforeEach(module("serviceStatusApp")); 

    var scope; 
    var statusService; 
    var controller; 
    var q; 
    var deferred; 

    // define the mock people service 
    beforeEach(function() { 
     statusService = { 
      getModuleStatus: function() { 
       deferred = q.defer(); 
       return deferred.promise; 
      } 
     }; 
    }); 

    // inject the required services and instantiate the controller 
    beforeEach(inject(function ($rootScope, $controller, $q) { 
     scope = $rootScope.$new(); 
     q = $q; 
     controller = $controller('serviceStatusController', { 
        $scope: scope, serviceStatusAppAPIservice: statusService }); 
    })); 

    describe("$scope.update", function() { 
     it("Updates screen", function() { 
      spyOn(statusService, 'getModuleStatus').andCallThrough(); 

      scope.update(); 

      deferred.resolve(); 

      expect(statusService.getModuleStatus).toHaveBeenCalled(); 
      expect(scope.modules).not.toBe([]); 
     }); 
    }); 
}); 

Также, как передать любые данные, полученные от службы, вызывающей стороне. В настоящее время в моей модели я делаю serviceStatusAppAPI.getModuleStatus(data), затем использую data.Data, чтобы выйти из возвращенного JSON.

ответ

0

Я предполагаю, что если вы делаете что-то подобное в вашем Ctrl

scope.update = function() { 
    serviceStatusAppAPIservice.setModuleStatus(url).then(function (data) { 
     scope.modules = data; 
    })  
}; 

Service, которая возвращает Promise

.factory('serviceStatusAppAPI', function($http, $q) { 
     return { 
      getModuleStatus: function() { 
       var defer = $q.defer(); 
       $http({method: 'GET', url: '/settings/getservicestatusandconfiguration'}) 
        .success(function(data, status, headers, config) { 
         // this callback will be called asynchronously 
         // when the response is available 
         defer.resolve(data); 
        }) 
        .error(function(data, status, headers, config) { 
         // called asynchronously if an error occurs 
         // or server returns response with an error status. 
         window.data = data; 
        }); 

       return defer.promise; 
      } 
     }; 
    }); 

Так вы контроллер вы получите данные, как это

serviceStatusAppAPI.getModuleStatus().then(function (data) { 
    $scope.modules = $filter('orderBy')(data.moduleData, 'ModuleName') 
}) 

Вот как вы можете запустить свой блок-тест устройства

beforeEach(function() { 

    var statusService = {}; 

    module('myApp', function($provide) { 
     $provide.value('serviceStatusAppAPIservice', statusService); 
    }); 

    statusService.modalStatus = { 
     moduleData: [{ModuleName: 'abc'}, {ModuleName: 'def'}] 
    }; 

    inject(function ($q) { 
     statusService.setModuleStatus = function() { 
      var defer = $q.defer(); 

      defer.resolve(this.modalStatus); 

      return defer.promise; 
     }; 

     statusService.getModuleStatus = function() { 
      var defer = $q.defer(); 

      defer.resolve(this.modalStatus); 

      return defer.promise; 
     }; 

    }); 
}); 

beforeEach(inject(function ($rootScope, $controller, _$stateParams_) { 
    scope = $rootScope.$new(); 
    stateParams = _$stateParams_; 
    controller = $controller; 
})); 

var myCtrl = function() { 
    return controller('ServiceStatusController', { 
       $scope: scope, 
      }); 
}; 

it('should load status', function() { 
    myCtrl(); 
    scope.update(); 
    scope.$digest(); 
    expect(scope.modules).toBe({ 
     status: 'active' 
    }); 
}); 
+0

Привет, Спасибо и да, вы в основном правы. Я обновил свой вопрос с помощью моей функции обновления. В настоящее время я получаю сообщение об ошибке 'getModuleStatus' – Chris

+0

Попробуйте указать точные данные, которые вы ожидаете в своем макетном сервисе. Я думаю, так как вы применяете $ filter и ожидаете чего-то из этого. Вам нужно предоставить точные данные, чтобы фильтр $ filter мог фильтровать результаты –

+0

может быть что-то вроде этого {moduleData: [{moduleName: 'Module1'}, {moduleName: 'newmodule'}]} –

Смежные вопросы