简体   繁体   English

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

[英]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 . 我正在运行一套使用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. 我意识到使用HttpClient意味着开始异步并且不适合我们总是告诉它等待的集成测试场景。 So this leads me to two questions that are somewhat related: 所以这引出了两个有些相关的问题:

  1. Is using HttpWebRequest / HttpWebResponse more appropriate for this scenario? 使用HttpWebRequest / HttpWebResponse更适合这种情况吗?
  2. Even if it is, what's the best way to work with HttpClient to handle errors on requests kicked off asynchronously? 即使是这样,使用HttpClient来处理异步启动的请求错误的最佳方法是什么?

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. 您可以在进行GetStringAsync调用之前使用_client.Timeout = timeoutInMilliseconds设置超时。 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. 但是,如果它当前是默认值(100秒),那么我的猜测是,当您发生这种情况时,您正在测试的远程服务器实际上已关闭。

More information on the timeout property can be found at: http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.timeout.aspx 有关超时属性的更多信息,请访问: 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. System.AggregateException来自同步运行的任务中发生的异常。 Using async tests allow the runner (in my case, NUnit) to decompose the task and get at the real exception. 使用异步测试允许运行器(在我的情况下,NUnit)分解任务并获得真正的异常。 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. 在方法签名中使用async Task然后await异步调用是执行这些类型测试的最佳方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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