AngularJS Promise Callback Not Trigged in JasmineJS Test

前端 未结 3 624
挽巷
挽巷 2021-02-05 01:02

Problem Intro

I\'m trying to unit test an AngularJS service that wraps the Facebook JavaScript SDK FB object; however, the test isn\'t working, and I have

3条回答
  •  北恋
    北恋 (楼主)
    2021-02-05 01:14

    From what I can see the problem of why your code isnt working is that you havent injected $scope. Michiels answer works cuz he injects $rootScope and call the digest cycle. However your $apply() is a higher level was of invoking the digest cycle so it will work as well... BUT! only if you inject it into the service itself.

    But i think a service doesn't create a $scope child so you need to inject $rootScope itself - as far as I know only controllers allow you to inject $scope as its their job to create well a $scope. But this is a bit of speculation, I am not 100 percent sure about it. I would try however with $rootScope as you know the app has a $rootScope from the creation of ng-app.

    'use strict';
    
    angular.module('app.services', [])
      .value('fbsdk', window.FB)
      .factory('Facebook', ['fbsdk', '$q', '$rootScope' function (FB, $q, $rootScope) { //<---No $rootScope injection
    
        //If you want to use a child scope instead then --> var $scope = $rootScope.$new();
        // Otherwise just use $rootScope
    
        FB.init({
          appId: 'xxxxxxxxxxxxxxx',
          cookie: false,
          status: false,
          xfbml: false
        });
    
        function getUserLoginStatus ($scope) { //<--- Use of scope here, but use $rootScope instead
          var deferred = $q.defer();
          // This is where the deferred promise is resolved. Notice that I call
          // `$scope.$apply()` at the end to let Angular know to trigger the
          // `then()` callback in the caller of `getUserLoginStatus()`.
          FB.getLoginStatus(function (response) {
            if (response.authResponse) {
              deferred.resolve(true);
            } else {
              deferred.resolve(false)
            }
            $scope.$apply(); // <-- Tell Angular to trigger `then()`. USE $rootScope instead!
          });
    
          return deferred.promise;
        }
    
        return {
          getUserLoginStatus: getUserLoginStatus
        };
      }]);
    

提交回复
热议问题