如何使用System.Net.Http.HttpClient处理异步异常并进行集成测试?

时间:2012-05-22 21:42:41

标签: c# unit-testing asynchronous dotnet-httpclient

我正在运行一套使用System.Net.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来处理异步启动的请求错误的最佳方法是什么?

2 个答案:

答案 0 :(得分:4)

正如之前的评论者建议的那样,您的联系可能已超时。您可以在进行GetStringAsync调用之前使用_client.Timeout = timeoutInMilliseconds设置超时。但是,如果它当前是默认值(100秒),那么我的猜测是你正在测试的远程服务器在发生这种情况时实际上是关闭的。

有关超时属性的更多信息,请访问:http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.timeout.aspx

答案 1 :(得分: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是执行这些类型测试的最佳方法。