I have an application that downloads massive amounts of pdfs from the web. From time to time, I get a HttpRequestException, contaning the message: Error while copying content to a stream.
So, I am trying to unit test my code to handle this situation. My current code for downloading is:
var request = await httpClient.GetAsync(url);
// This is where the exception would be thrown
await request.Content.ReadAsByteArrayAsync());
Now I am trying to simulate a HttpRequestException, so that I can unit test the code above, but I dont know how to do it. Can anyone please help?
Thanks in advance!
The key here is creating an HttpContent that throws an exception:
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;
}
}
Once you have that, you can use something like my own mockhttp to mock the request:
var handler = new MockHttpMessageHandler();
handler.When("http://tempuri.org/url")
.Respond(new ExceptionThrowingContent(ex));
var mockClient = new HttpClient(handler);
// pass mockHandler to your component
Now, if your component passes in HttpCompletionOption.ResponseHeadersRead when it makes the request, the exception will be thrown at await Content.ReadAsByteArrayAsync(). If not, HttpClient will attempt to buffer the response so the exception will be thrown at await HttpClient.GetAsync().
If the response is being buffered, it's realistically "impossible" for an exception to be thrown at ReadAsByteArrayAsync so there's no point in attempting to simulate it. ("impossible" outside an OutOfMemoryException)
With MockHttp it is easy setup HttpClient tests in a fluent manner you can return a customized HttpContent that throws a HttpRequestException like in this example.
[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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With