简体   繁体   中英

How can I handle async exceptions using System.Net.Http.HttpClient with my integration tests?

I'm running a suite of integration tests that use System.Net.HttpClient . Most of our "act" sections in these tests use this general format:

// Arrange
// Do some stuff

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

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

However, running these tests intermittently yields something like this:

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()

I realize using HttpClient is meant for kicking off things async and isn't a perfect fit for our integration test scenarios where we always tell it to wait. So this leads me to two questions that are somewhat related:

  1. Is using HttpWebRequest / HttpWebResponse more appropriate for this scenario?
  2. Even if it is, what's the best way to work with HttpClient to handle errors on requests kicked off asynchronously?

As the previous commenters suggested, your connection is probably timing out. You can set the timeout with _client.Timeout = timeoutInMilliseconds before making the GetStringAsync call. However, if it is currently the default (100 seconds) then my guess is that the remote server you are testing against is actually down when this occurs.

More information on the timeout property can be found at: http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.timeout.aspx

System.AggregateException comes from exceptions that happen in a task run synchronously. Using async tests allow the runner (in my case, NUnit) to decompose the task and get at the real exception. So what the above code should've looked like is this:

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

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

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

Using async Task in the method signature and then await on the asynchronous calls is the best way to execute these sorts of tests.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM