[英]Jasmine: Calling then in AngularJS Promise
我的AngularJS控制器具有以下功能:
service.getPlaceByAddress = function(address) {
return $q(function(resolve, reject) {
geocoder().geocode({'address': address}, function(result, status) {
// gets called
if (status === google.maps.GeocoderStatus.OK) {
return resolve(result);
}
return reject();
});
});
};
我想測試這段代碼,但是then函數不會被調用。 但是地址解析功能肯定會被調用。
it('returns an error if the data service returns no results', function(done) {
GoogleMaps.getPlaceByAddress('Testlocation').then(function() {
done();
// gets never called
});
$scope.$digest();
});
相反,我得到一個異步超時:
錯誤:超時-jasmine.DEFAULT_TIMEOUT_INTERVAL指定的超時內未調用異步回調。
編輯
當我直接返回resolve
,它可以按預期工作:
service.getPlaceByAddress = function(address) {
return $q(function(resolve, reject) {
return resolve();
//geocoder()...
});
};
因此,我認為問題出在地址解析器的回調中。 這很奇怪,因為代碼可以在瀏覽器中完美地運行,但不能在茉莉花測試中...
我認為問題在於您正在調用真正的異步服務,而不是在單元測試中將其虛擬化。 如果您有一個虛擬服務立即完成承諾,則測試只需調用$scope.$digest()
一次即可觸發then()
回調,但是如果它是真正的異步調用,則摘要將在遠程服務器有機會實際發送回任何數據。
最好的解決方案是虛擬掉測試的異步部分。 因此,在此測試中,您將放置geocoder().geocode()
的存根,將其與TestLocation
作為參數一起調用時,僅會立即成功完成,失敗或對每個代碼進行測試。
或者,您可以有一個循環,等待直到請求確實有機會完成為止,但這對於單元測試來說是不好的樣式,因為它們應該是獨立的並且不依賴於遠程服務器。
根據您的評論:
您鏈接的博客文章顯示了如何模擬對Geocoder的調用,但是在該博客文章中,它只是驗證是否已調用geocoder方法,實際上並沒有在測試服務承諾是否得到解決以及所使用的間諜程序是否在測試中。只是返回一個不會觸發回調的值。
因此,我認為您需要以他們所做的為基礎:添加一個實際上會觸發回調的間諜,但是與promises相關的一切都是異步的,因此您將需要調用$digest()
來強制完成promise。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.