簡體   English   中英

Angular.js承諾在使用業力進行單元測試服務時無法解決

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

我正在嘗試對Angular.js服務進行單元測試,並且需要對從Mock服務返回的promise(使用Jasmine)設置一個期望值。 我正在使用業力單元測試框架。 相關的代碼段如下:

// I can't figure out how to do the equivalent of a $scope.$digest here. 
var loginStatusPromise = FacebookService.getFacebookToken();
loginStatusPromise.then(function(token) {
    expect(false).toBeTruthy(); // If this test passes, there is something going wrong!
    expect(token).not.toBeNull(); // The token should be ValidToken
    expect(token).toBe('ValidToken');
});

完整的單元測試代碼可以在這里看到。

問題是promise.then語句在執行業力時永遠不會觸發。 因此,我的期望陳述都沒有被執行。 在我的控制器測試中,我使用$ scope。$ digest()來解決承諾,但我不清楚在服務測試中如何做到這一點。 我認為在服務測試中沒有“范圍”的概念。

我在這里有錯誤的結尾嗎? 我是否需要將$ rootScope注入我的服務測試,然后使用$ digest? 或者,還有另一種方式嗎?

我遇到了這個問題並通過簡單地在測試結束時添加$rootScope.$apply()解決它

根據@mpm的建議,您的FacebookService可能是個問題。 你確定它沒有在Facebook依賴關系中發生任何http調用,這在單元測試期間不會發生嗎? 你確定已經延遲調用了resolve嗎?

假設您正在使用ngFacebook / ngModule快速說明解決方案/想法之前該項目沒有單元測試! 您確定要使用此項目嗎?

我在Github上快速掃描了你的單元測試,發現以下缺失: -

1)模塊初始化 ngFacebook需要或者你需要初始化你做同樣事情的模塊。

beforeEach(module('ngFacebook'));

要么

beforeEach(module('yieldtome'));

2)認真考慮模擬ngFacebook模塊

在單元級別測試中,您將在模擬氣泡中測試代碼,其中外部接口被刪除。

否則)嘗試添加調用API,如下所示: -

 $rootScope.$apply(function() {
     this.FacebookService.getFacebookToken().then(function(){
        //your expect code here
     });
    });
 $httpBackend.flush();//mock any anticipated outgoing requests as per [$httpBackend][2]
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

我同意上述答案,即服務應該與$rootScope無關。

在我的情況下有一個$q承諾,它使用了第二個服務在內部解決了一個承諾。 無法解決外部問題,除非我將$rootScope.$digest()到我的服務代碼中(不是測試)...

我最終編寫了這個快速的墊片,以便在我的測試中使用$q ,但要小心,因為它只是一個例子,而不是一個完整的$q實現。

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);
        }
      };
    }
  });
}));

希望它對某人有用,或者如果您有任何反饋。

謝謝。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM