2013-07-02 90 views
19

我們用因果報應單元測試我們的角度服務,這些服務包含$ HTTP調用,所以我們有一個嘲笑$ httpbackend到位,使我們可以在沒有服務器和數據庫運行應用程序。 這工作正常,服務可以調用$ http(「someurl?id = 1234」),我們得到正確的數據。角1.1.5測試基於承諾服務

但是,當我們試圖做同樣的事情在單元測試中,我們無法得到它的工作,承諾永遠不會解決,當它涉及到$ HTTP

服務:

getAllowedTypes: function (contentId) { 
    var deferred = $q.defer(); 
    $http.get(getChildContentTypesUrl(contentId)) 
     .success(function (data, status, headers, config) { 
      deferred.resolve(data); 
     }). 
     error(function (data, status, headers, config) { 
      deferred.reject('Failed to retreive data for content id ' + contentId); 
     }); 
    return deferred.promise; 
} 

嘲笑$ httpbackend

$httpBackend 
    .whenGET(mocksUtills.urlRegex('/someurl')) 
    .respond(returnAllowedChildren); //returns a json object and httpstatus:200 

測試

it('should return a allowed content type collection given a document id', function(){ 

    var collection; 
    contentTypeResource.getAllowedTypes(1234).then(function(result){ 
     collection = result; 
    }); 

    $rootScope.$digest(); 

    expect(collection.length).toBe(3); 
}); 

但是集合是未定義的.then()永遠不會被調用。

試圖幾乎一切辦法去解決,$ rootScope承諾。$適用(),$消化,$ httpBacke.flush(),但沒有任何工程

因此嘲笑$ httpBackend從控制器調用時工作應用程序,而不是在服務中人緣單位直接調用測試

回答

7

由於$ httpBackend.flush()調用自身摘要,因此不應該消化兩次。 你必須進行呼叫,調用摘要來解析請求攔截器,調用flush。

這裏是一個工作Plnkr:http://plnkr.co/edit/FiYY1jT6dYrDhroRpFG1?p=preview

+1

Kees de Kooter在下面的另一個答案中發表了評論,認爲$ rootScope不是必需的。我分叉plunkr並評論了所有$ rootScope的用法。測試仍然通過:http://plnkr.co/edit/4ladJi7TAQ4sFdzuGmDr?p=preview – chashi

4

你的情況,你必須$消化兩次,一次爲$ httpBackend,並再次爲自己的推遲。

所以:

it('should return a allowed content type collection given a document id', function(){ 

    var collection; 
    contentTypeResource.getAllowedTypes(1234).then(function(result){ 
     collection = result; 
    }); 
    $httpBackend.flush(); 
    $rootScope.$digest(); 

    expect(collection.length).toBe(3); 
}); 
+0

嘗試.flush()了,但得到: 「錯誤:沒有掛起的請求衝!」這似乎是自1.1.4以來的一個常見錯誤:https://github.com/angular/angular.js/issues/2431 –

+0

訂單在這裏是不正確的,你需要在你刷新之前$摘要。 – user553086

4

你幾乎沒有。就你而言,你只需要在刷新HTTP後端之前強制一個摘要循環。請參閱以下示例代碼。

it('should return a allowed content type collection given a document id', function(){ 

    var collection; 
    contentTypeResource.getAllowedTypes(1234).then(function(result){ 
     collection = result; 
    }); 

    $rootScope.$digest(); 
    $httpBackend.flush(); 
    expect(collection.length).toBe(3); 
}); 
+0

它是.flush()no。$ flush()btw和nope,不工作,得到「沒有待處理的請求刷新」錯誤,請參閱:https://github.com/angular/angular.js/issues/2431 –

+2

$ rootScope。如果您單獨測試服務,$ digest()是IMO不必要的。 –