Angular.js promise not resolving when unit testing service with karma

前端 未结 4 1291
梦如初夏
梦如初夏 2021-01-18 19:03

I am trying to unit test an Angular.js service, and need to set an expect on a promise returned from a Mock service (using Jasmine). I am using the karma unit testing framew

相关标签:
4条回答
  • 2021-01-18 19:26

    I had this problem and resolved it by simply putting a $rootScope.$apply() at the end of my test

    Your FacebookService might be the issue, as suggested by @mpm. Are you sure it doesn't have any http calls happening inside of that Facebook dependency which wouldn't be occurring during unit testing? Are you certain that resolve has been called on the deferred yet?

    0 讨论(0)
  • 2021-01-18 19:28
    beforeEach(function(){
       var self=this;
        inject(function($rootScope,Facebook){
            self.$rootScope=$rootScope;
            self.Facebook=Facebook;
        });
    })
    
    it('resolves unless sourcecode broken',function(done){
        // I can't figure out how to do the equivalent of a $scope.$digest here. 
        var loginStatusPromise = this.FacebookService.getFacebookToken();
        loginStatusPromise.then(function(token) {
            expect(token).toBe('ValidToken');
            done();
        });
        $rootscope.$apply();
    
    });
    

    https://docs.angularjs.org/api/ng/service/$q

    0 讨论(0)
  • 2021-01-18 19:28

    I agree with the above answers that a service should have nothing to do with $rootScope.

    In my case had a $q promise, that used a second service internally resolving to a promise as well. No way to resolve the external one, unless I added $rootScope.$digest() into my service code (not the test)...

    I ended-up writing this quick shim for $q to use in my tests, but be careful, as it's just an example and not a complete $q implementation.

    beforeEach(module(function($provide) {
      $provide.value('$q', {
        defer: function() {
          var _resolve, _reject;
          return {
            promise: {
              then: function (resolve, reject) {
                _resolve = resolve;
                _reject = reject;
              }
            },
            resolve: function (data) {
              window.setTimeout(_resolve, 0, data);
            },
            reject: function (data) {
              window.setTimeout(_reject, 0, data);
            }
          };
        }
      });
    }));
    

    Hope it will be useful to someone, or if you have any feedback.

    Thanks.

    0 讨论(0)
  • 2021-01-18 19:34

    Assuming that you are using ngFacebook/ngModule a quick note before the solution/ideas is that this project does not have unit tests ! Are you sure you want to use this project ?

    I did a quick scan of your Unit Tests on Github and found following missing:-

    1) Module initialization. ngFacebook needs that or you need to initialize your module that does the same thing.

    beforeEach(module('ngFacebook'));
    

    OR

    beforeEach(module('yieldtome'));
    

    2) Seriously consider mocking ngFacebook module

    At unit level tests you are testing your code within a mocked bubble where outside interfaces are stubbed out.

    Otherwise) Try adding calling the API as below:-

     $rootScope.$apply(function() {
         this.FacebookService.getFacebookToken().then(function(){
            //your expect code here
         });
        });
     $httpBackend.flush();//mock any anticipated outgoing requests as per [$httpBackend][2]
    
    0 讨论(0)
提交回复
热议问题