title: Jasmine spyOn does not mock function correctly
body: <p>So I have a function like so:</p>
  
  <pre><code>        function initializeView() {
              var deferred = $q.defer();
              var deleteOrUploadToBestMoments = this.deleteOrUploadToBestMoments;
              var checkAndDeleteExpiredMoments = this.checkAndDeleteExpiredMoments;
  
              getNearbyMoments()
              .then(deleteOrUploadToBestMoments)
              .then(checkAndDeleteExpiredMoments).then(function(moments) {
                  //omitted
                  }, function(error) {
                      deferred.reject(error);
                  });
              return deferred.promise;
          };
  </code></pre>
  
  <p>I wouldl ike to test this function with a unit test.  Here is my test:</p>
  
  <pre><code>it('Should call initializeView', function(done) {
      spyOn(service, 'getNearbyMoments').and.callFake(function() {
          console.log("MOCKED getNearbyMoments");
          return $q.resolve(mockOutMoments());
      });
      spyOn(service, 'deleteOrUploadToBestMoments').and.callFake(function() {
          console.log("MOCKED deleteOrUploadToBestMoments");
          return $q.resolve();
      });
      spyOn(service, 'checkAndDeleteExpiredMoments').and.callFake(function() {
          console.log("MOCKED checkAndDeleteExpiredMoments");
          return $q.resolve();
      });
      service.initializeView().then(function(moments) {
          //omitted
          done();
      });
      $scope.$apply();
  });
  </code></pre>
  
  <p>The problem is with the spyOn functions.  It is not mocking the correct functions.  However, it does mock it out correctly if I add a 'this' in front of getNearbyMoments in my production code like so:</p>
  
  <pre><code>   function initializeView() {
          var deferred = $q.defer();
          var deleteOrUploadToBestMoments = this.deleteOrUploadToBestMoments;
          var checkAndDeleteExpiredMoments = this.checkAndDeleteExpiredMoments;
  
          this.getNearbyMoments()
          .then(deleteOrUploadToBestMoments)
          .then(checkAndDeleteExpiredMoments).then(function(moments) {
              //omitted
              }, function(error) {
                  deferred.reject(error);
              });
          return deferred.promise;
      };
  </code></pre>
  
  <p>I could just add a 'this' in front of all my function calls in my production code but this becomes a problem when the context of 'this' changes.  Also, I shouldn't need to change my production code just to make my tests happy - Which makes me really want to figure out what I am doing wrong in my tests so I don't put a band-aid on a potential huge problem.</p>
  
  <p>EDIT:</p>
  
  <p>Apparently I was doing it correctly using 'this'.  But the problem is that whenever I do that I get an error saying</p>
  
  <pre><code>'TypeError: this.getNearbyMoments is not a function`
  </code></pre>
  
  <p>Heres my code:</p>
  
  <pre><code>function initializeView() {
              var deferred = $q.defer();
              var deleteOrUploadToBestMoments = this.deleteOrUploadToBestMoments;
              var checkAndDeleteExpiredMoments = this.checkAndDeleteExpiredMoments;
              var getNearbyMoments = this.getNearbyMoments;
              this.getNearbyMoments()
              .then(deleteOrUploadToBestMoments)
              .then(checkAndDeleteExpiredMoments).then(function(moments) {
                  //omitted
                  }, function(error) {
                      console.log("ERROR");
                      console.log(error);
                      deferred.reject(error);
                  });
              return deferred.promise;
          };
  </code></pre>
  
  <p>For some context my service looks something like this:</p>
  
  <pre><code>(function() {
      angular.module('app.momentsService', [])
  
      .service('momentsService', ['core', '$q', 'constants', 'logger', 'geolocation', 'awsServices', 'localStorageManager', momentsService]);
  
      function momentsService(core, $q, constants, logger, geolocation, awsService, localStorageManager){
  
  //Lots of other functions
          this.checkAndDeleteExpiredMoments = checkAndDeleteExpiredMoments;
          this.getNearbyMoments = getNearbyMoments;
          this.deleteOrUploadToBestMoments = deleteOrUploadToBestMoments;
  
          function getNearbyMoments() {
  //Omitted...
         };
  function initializeView() {
  //Well, you already know whats in here...
  };
  </code></pre>
  
  <p>So I'm confused because I clearly define the function at the top of the service but for some reason it does not know that it exists.  </p>