2014-07-22 42 views
2

以下控制器正在获取TypeError:'undefined'不是函数(评估sessionService.getCurrentPlace())。我有一个模拟服务,该方法被窥探。模拟服务上的另一种方法很好。我试过.AndReturns({..})的间谍以及.AndCallThrough()但没有运气。任何想法我错过了什么,或者我正在解决这个错误?非常感谢!角单元测试茉莉间谍错误

控制器:

'use strict'; 

angular.module('wallyApp') 
    .controller('addGatewayCtrl', function ($scope, $location, $filter, sessionService) { 
     /* 
      private members 
     */ 
     //set scope from session data 
     $scope.processSession = function (places) { 
      $scope.currentPlaceId = sessionService.getCurrentPlace(); 
      if (!$scope.currentPlaceId) { 
       $scope.currentPlaceId = places[0].id; 
      } 
      $scope.place = $filter("getById")(places, $scope.currentPlaceId); 
      $scope.ready = true; 
     }; 

     /* 
      setup our scope 
     */ 
     $scope.currentPlaceId = null; 
     $scope.place = {}; 
     $scope.videoSrc = "/videos/gateway-poster.gif"; 
     $scope.loaded = true; 

     /* 
      setup controller behaivors 
     */ 

     //set video or gif to show or hide video 
     $scope.setVideo = function() { 
      $scope.videoSrc = "/videos/gateway.gif"; 
     }; 
     $scope.setPoster = function() { 
      $scope.videoSrc = "/videos/gateway-poster.gif"; 
     }; 
     //initialize scope 
     $scope.setVideo(); 

     //submit form 
     $scope.continue = function() { 
      $location.path("/setup/pair-gateway"); 
      return false; 
     }; 
     //cancel 
     $scope.back = function() { 
      $location.path("/setup/plan-locations"); 
      return false; 
     }; 
     //wifi 
     $scope.gotoWifi = function() { 
      $location.path("/setup/wifi"); 
      return false; 
     }; 


     /* 
      setup our services, etc 
     */ 
     //get our places from the cache 
     sessionService.get("places").then(function (places) { 
      if (!places || places.length < 1) { 
       sessionService.refreshPlaces(); //Note we don't care about the promise as our broadcast watch will pick up when ready 
      } else { 
       $scope.processSession(places); 
      } 
     }).catch(function (error) { 
      //TODO:SSW Call Alert Service?? 
     }); 

     //Watch broadcast for changes 
     $scope.$on("draco.placesRefreshed", function (event, data) { 
      sessionService.get("places").then(function (places) { 
       $scope.processSession(places); 
      }); 
     }); 
    }); 

单位测试:

'use strict'; 

describe('addGatewayCtrl', function() { 
    var $q, 
     $rootScope, 
     $location, 
     $scope, 
     $filter, 
     mockSessionService, 

     completePath = "/setup/pair-gateway", 
     backPath = "/setup/plan-locations", 
     wifiPath = "/setup/wifi", 
     sessionDeferred, 
     sessionInitDeferred, 

     mockPlaces = [{ id: "0001" }]; 

    beforeEach(module('wallyApp')); 

    beforeEach(inject(function (_$q_, _$rootScope_, _$location_, _$filter_) { 
     $q = _$q_; 
     $location = _$location_; 
     $rootScope = _$rootScope_; 
     $filter = _$filter_; 
    })); 

    beforeEach(inject(function ($controller) { 
     $scope = $rootScope.$new(); 

     mockSessionService = { 
      get: function (contact) { 
       sessionDeferred = $q.defer(); 
       return sessionDeferred.promise; 
      }, 
      getCurrentPlace: function() { 
       return mockPlaces[0].id; 
      }, 
      refreshPlaces: function() { 
       sessionInitDeferred = $q.defer(); 
       return sessionInitDeferred.promise; 
      } 
     }; 

     spyOn(mockSessionService, 'get').andCallThrough(); 
     spyOn(mockSessionService, 'getCurrentPlace').andReturn(mockPlaces[0].id); 
     spyOn(mockSessionService, 'refreshPlaces').andCallThrough(); 

     $controller('addGatewayCtrl', { 
      '$scope': $scope, 
      '$location': $location, 
      '$filter':$filter, 
      'sessionService': mockSessionService 
     }); 

    })); 

    describe('call session service to get place data ', function() { 

     //resolve our mock place and session services 
     beforeEach(function() { 
      //resolve mocks 
      sessionDeferred.resolve(mockPlaces); 

      $rootScope.$apply(); 
     }); 

     //run tests 
     it('should have called sessionService get places', function() { 
      expect(mockSessionService.get).toHaveBeenCalledWith("places"); 
     }); 
     it('should have called sessionService get currentPlaceId', function() { 
      expect(mockSessionService.getCurrentPlace).toHaveBeenCalled(); 
     }); 
     it('should have set scope', function() { 
      expect($scope.place).toEqual(mockPlaces[0]); 
     }); 

    }); 

}); 

回答

0

所以我想通了。使用嵌套延迟的时候,你必须调用$ scope()之间的apply()。下面固定起来(有一些小的改动,以模拟数据的响应,但这些都是微不足道的):

 //resolve promises 
     activityMessagesDeferred.resolve(mockActivityMessages); 
     $rootScope.$apply(); 
     $rootScope.$broadcast("draco.sessionRefreshed"); 
     activityCountDeferred.resolve(mockActivityCount); 
     $rootScope.$apply(); 

     placesDeferred.resolve(mockPlaces); 
     activityListDeferred.resolve(mockActivities); 
     $rootScope.$apply(); 
+0

使用'$ rootScope $摘要();'是所有需要,并会导致英寸一个更快的测试。 –