2017-03-27 18 views
1

我已經得到了下面的函數在我AngularJS控制器:茉莉:調用然後在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(); 
     }); 
    }); 
}; 

我想測試這段代碼,但當時的功能會不會被調用。但是,地理編碼功能肯定會被調用。

it('returns an error if the data service returns no results', function(done) { 
    GoogleMaps.getPlaceByAddress('Testlocation').then(function() { 
     done(); 
     // gets never called 
    }); 

    $scope.$digest(); 
}); 

相反即時得到一個異步超時:

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

編輯

當我直接返回resolve,它按預期工作:

service.getPlaceByAddress = function(address) { 
    return $q(function(resolve, reject) { 
     return resolve(); 
     //geocoder()... 
    }); 
}; 

所以我認爲,問題在於電話ack的地理編碼器。這是奇怪的,因爲代碼完全在瀏覽器中,而不是在茉莉測試...

+0

問題是完成的參數。 看到這個: http://stackoverflow.com/questions/22604644/jasmine-async-callback-was-not-invoked-within-timeout-specified-by-jasmine-defa – Luca

+0

@Luca:可惜這不是解決方案。如果我刪除'done'參數,承諾不會解決...:/ – roNn23

回答

2

我認爲問題是,你在呼喚一個真正的異步服務,而不是在你的單元測試dummying出來的。如果您有完成一個承諾立即然後虛擬服務就足夠了測試調用$scope.$digest()一旦觸發then()回調,但如果它是一個真正的異步調用摘要將在遠程服務器之前被稱爲有機會實際發送返回任何數據。

的最佳解決方案是虛設出測試的異步部分。因此,在這個測試,你會把在geocoder().geocode()存根當與TestLocation稱爲參數簡單地完成馬上成功,或者失敗,或者用做一次測試。

或者你可以有一個循環,等待,直到要求真正有機會來完成,但是這是很糟糕風格單元測試,因爲他們應該是獨立的,不依賴遠程服務器上。

從您的評論:

您鏈接的博客文章將向您展示如何嘲笑調用地理編碼器,但在博客中它只是驗證了地理編碼方法被調用,它實際上沒有測試該服務承諾已解決,並且使用的間諜僅返回一個不觸發回調的值。

所以我認爲你需要建立在他們所做的事情上:添加一個實際觸發回調的間諜,但連接到承諾的所有東西都是異步的,所以你需要調用$digest()來強制承諾完成。

+0

謝謝。我認爲你是對的,測試不能與真正的異步服務正常工作。正因爲如此,我嘲笑了數據,如下所示:https://kwilson.io/blog/mock-out-google-maps-geocoder-with-jasmine-spies/但我已經習慣了調用'$ scope。$ digest()',這在操作方法中沒有提及。 – roNn23