2016-08-26 161 views
3

我有一個應用程序可以從網上下載大量的pdf。有時候,我得到一個HttpRequestException異常,包含消息:將內容複製到流時出錯。模擬單元測試的HttpRequestException

所以,我試圖單元測試我的代碼來處理這種情況。我對目前的下載代碼:

var request = await httpClient.GetAsync(url); 

// This is where the exception would be thrown 
await request.Content.ReadAsByteArrayAsync()); 

現在我試圖模擬一個HttpRequestException,這樣我就可以進行單元測試上面的代碼,但我不知道該怎麼做。任何人都可以幫忙嗎?

提前致謝!

+0

摘要您控制的接口後面的httpClient調用,以便您可以在單元測試期間模擬它以提升/模擬所需的異常。從命名角度來看,'GetAsync'的結果將是'response'而不是'request'。即'var response = await httpClient.GetAsync(url);' – Nkosi

+0

我沒有考慮過這個用例。我會考慮在mockhttp中添加一個新的API,以便將來更輕鬆。 –

+0

謝謝。請儘可能更新。 –

回答

2

這裏的關鍵是建立一個HttpContent拋出異常:

public class ExceptionThrowingContent : HttpContent 
{ 
    private readonly Exception exception; 
    public ExceptionThrowingContent(Exception exception) 
    { 
     this.exception = exception; 
    } 

    protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) 
    { 
     return Task.FromException(exception); 
    } 

    protected override bool TryComputeLength(out long length) 
    { 
     length = 0L; 
     return false; 
    } 
} 

一旦你有,你可以使用像我自己mockhttp嘲笑請求:

var handler = new MockHttpMessageHandler(); 
handler.When("http://tempuri.org/url") 
    .Respond(new ExceptionThrowingContent(ex)); 

var mockClient = new HttpClient(handler); 

// pass mockHandler to your component 

現在,如果您的組件在發出請求時通過了HttpCompletionOption.ResponseHeadersRead,則將拋出異常await Content.ReadAsByteArrayAsync()。如果不是,HttpClient將嘗試緩衝響應,以便在await HttpClient.GetAsync()引發異常。

如果響應被緩衝,這是現實「不可能」的一個例外,在ReadAsByteArrayAsync拋出所以有在試圖模仿它沒有任何意義。 (OutOfMemoryException之外的「不可能」)

+0

看起來真的很棒!!!你認爲有可能在await response.Content.ReadAsByteArrayAsync()引發異常嗎? ;?我沒有足夠清楚:(對不起。截至目前,異常正在等待提示mockClient.GetAsync(「http://tempuri.org/url」) –

+0

更新爲返回拋出異常的Tas改爲k。放手吧。 –

+0

沒有工作:(如果你可以騰出一些時間來檢查這一點,我會很感激 –

1

隨着MockHttp很容易安裝在流利地HttpClient測試,你可以返回定製HttpContent拋出一個HttpRequestException就像這個例子。

[TestMethod] 
[ExpectedException(typeof(HttpRequestException))] 
public async Task Test() 
{ 
    var content = new ContentWithException(); 
    var mockHttp = new MockHttpMessageHandler(); 
    mockHttp.Expect("http://localhost/mypdfDownload").Respond(content); 

    var client = new HttpClient(mockHttp); 
    var response = await client.GetAsync("http://localhost/mypdfDownload"); 

    await response.Content.ReadAsByteArrayAsync(); 
} 

private class ContentWithException : HttpContent 
{ 
    protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) 
    { 
     throw new HttpRequestException(); 
    } 

    protected override bool TryComputeLength(out long length) 
    { 
     length = 0; 
     return false; 
    } 
} 
+0

看起來真棒!你認爲有可能在等待response.Content.ReadAsByteArrayAsync()時拋出異常嗎? ?我沒有足夠清楚:(對不起。 截至目前,異常正在等待client.GetAsync(「http:// localhost/mypdfDownload」) –

+0

@FernandoSilva:我看着它,我還沒有上來在這兩種情況下(比如在@Richard Szalay的回答中),HttpClient從'GetAsync'開始訪問內容(異步緩衝),所以在'ReadAsByteArrayAsync()'中拋出異常, 。 –

+0

Thanks,Please,update when you have a chance –