如何在集成测试中使用 System.Net.Http.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 来处理异步启动的请求错误的最佳方法是什么?

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

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

>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是执行此类测试的最佳方式。

最新更新