title: Angular Unit Test Jasmine Spy error
body: <p>The following controller is getting a TypeError: 'undefined' is not a function (evaluating <code>sessionService.getCurrentPlace()</code>).  I have a Mock Service with that method being spied on.  The other method on the mock service works fine.  I've tried <code>.AndReturns({..})</code> on the spy as well as <code>.AndCallThrough()</code> but no luck.  Any idea what I'm missing, or am I going about this wrong?  Much Thanks!</p>
  
  <p>CONTROLLER:</p>
  
  <pre><code>    '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 &lt; 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);
              });
          });
      });
  </code></pre>
  
  <p>UNIT TEST:</p>
  
  <pre><code>    '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]);
          });
  
      });
  
  });
  </code></pre>