2012-05-22 99 views
8

我正在運行一套使用System.Net.HttpClient的集成測試。在這些測試中的大多數我們的「行爲」部分的使用一般格式爲:如何使用System.Net.Http.HttpClient處理異步異常並進行集成測試?

// Arrange 
// Do some stuff 

// Act 
var download = _client 
    .GetStringAsync(testUrl) 
    .Result; 

// Assert 
// Does "download" contain what I expected? 

然而,運行這些測試間歇性地產生這樣的:

System.AggregateException : One or more errors occurred. 
    ----> System.Threading.Tasks.TaskCanceledException : A task was canceled. 
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken) 
at System.Threading.Tasks.Task`1.get_Result() 

我體會到使用HttpClient是爲蹬掉的東西異步,並且不適合我們的集成測試場景,我們總是讓它等待。因此,這導致我兩塊有點相關的問題:

  1. 是使用HttpWebRequest/HttpWebResponse更適合於這種情況?
  2. 即使是這樣,使用HttpClient來處理異步啓動的請求錯誤的最佳方式是什麼?
+0

你爲什麼以異步方式開始?似乎你想同步做到這一點......所以我會對第一個問題說「是」。對於問題#2,我會增加HttpClient類的'Timeout'屬性,除非您需要在特定時間範圍內測試響應性。無論哪種方式,我不知道爲什麼異步會更適合單元測試... – Tom

+1

Httpclient只提供異步方法。 OP通過在任務上調用結果正確地將它們轉換爲同步調用。這也嚴格意味着這不是異步異常,它是在「結果」上阻塞之後引發的同步異常。我會嘗試增加超時時間 – aL3891

回答

3

正如之前的評論者所建議的,您的連接可能會超時。在進行GetStringAsync調用之前,您可以使用_client.Timeout = timeoutInMilliseconds來設置超時。但是,如果它目前是默認值(100秒),那麼我猜測您正在測試的遠程服務器實際上是在發生這種情況時停止運行。對超時屬性

的更多信息,可以發現:http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.timeout.aspx

1

System.AggregateException來自於一個任務同步運行發生異常。使用異步測試允許跑步者(在我的情況下,NUnit)分解任務並獲得真正的異常。那麼,上面的代碼應該已經看起來是這樣的:

[Test] 
public async Task DownloadContainsWhatIExpected() 
{ 
    // Arrange 
    // Do some stuff 

    // Act 
    var download = await _client 
     .GetStringAsync(testUrl); 

    // Assert 
    // Does "download" contain what I expected? 
} 

使用的異步調用的方法簽名async Task然後await是執行這些各種各樣的測試的最佳方法。

+0

沒錯!我只是假設單元測試框架與async/await不兼容,而我正在使用.Wait()和.Result。謝謝你讓我變直! – Skrymsli