![](/img/trans.png)
[英]Unit testing $q promise within Angular service - Karma, Jasmine
[英]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();
});
我同意上述答案,即服務應該與$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.