2014-09-24 87 views
4

我想測試我的服務是使用緩存的GET請求拋出錯誤。

簡單化了測試的版本:

var url = "/test"; 
    var whenTestRequest = $httpBackend.when('GET', url); 

    whenTestRequest.respond(200, "r1"); 
    $http({ url: url, method: 'GET', cache: true }).success(function (value) { 
    expect(value).toBe("r1"); 
    }); 
    $httpBackend.flush(); 

    whenTestRequest.respond(200, "r2"); 
    $http({ url: url, method: 'GET', cache: true }).success(function (value) { 
    expect(value).toBe("r1"); 
    }); 
    $httpBackend.flush(); 

我需要第二$httpBackend.flush()使我的第二個success函數被調用,而是flush是第二次調用拋出:

Error: No pending request to flush !

所以我需要在try/catch中包裝flush。這有效,但是有沒有正確的方法來處理這個問題?

+0

另一種方法是切換到使用'$ httpBackend.expectGET()''而不是$ httpBackend.when()'。原因在於「期望」版本更爲嚴格,您可以測試只有一個HTTP請求。這種方法顯着改變你的測試。坦率地說,我從未在測試中使用「when」函數b/c,我想斷言HTTP請求是按照我預期的順序/數量進行的。 – 2014-09-25 05:53:30

+1

這只是咬我一口......我們不能成爲第一個遇到這個問題的人,我們可以嗎? – 2015-03-03 23:06:07

回答

0

我想我找到了解決方案 - 而不是調用$httpBackend.flush(),請致電$rootScope.$digest()。這就是flush最終在後臺執行的操作,除非不檢查是否有任何待處理的請求,並且會導致緩存滿足的$ http請求的承諾得到解決。

我就遇到了這個當我在模板緩存而不是做對每一個HTTP請求交換我的一個項目來存儲指令的模板。我的老測試所創建的指令,像這樣:

beforeEach(inject(function($compile, $rootScope, $httpBackend) { 
    $httpBackend.expectGET('login.html').respond('<div></div>'); 
    $compile('<login-page/>')($rootScope); 
    $httpBackend.flush(); 
})); 

然而,當我切換測試使用的模板,刷新扔的例外,因爲該請求被緩存滿意,從來沒有在虛擬線路。但即使在刪除了$ httpBackend之後,該指令仍然沒有建立,因爲templateUrl導致整個指令初始化進程在then調用模板請求的承諾中。即使高速緩存將滿足模板請求,代碼還是去了大部分的方式,通過$http電話,但因爲請求不在緩存中結束了這$httpBackend預期,有沒有明顯的方式來獲得的承諾鏈實際運行。

經過一番調查和測試,事實證明,$rootScope.$digest()將導致承諾運行,所以更改代碼這樣:

beforeEach(inject(function($compile, $rootScope) { 
    $compile('<login-page/>')($rootScope); 
    $rootScope.$digest(); 
})); 

這使beforeEach運行,而該指令實際上有內置,允許其餘的測試繼續正常進行。