【问题标题】:How can I handle async exceptions using System.Net.Http.HttpClient with my integration tests?如何在集成测试中使用 System.Net.Http.HttpClient 处理异步异常?
【发布时间】:2012-05-22 21:42:41
【问题描述】:

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

【问题讨论】:

  • 一开始为什么要异步执行此操作?似乎您想同步进行...所以我对问题#1说是。对于问题 #2,我会增加 HttpClient 类的 Timeout 属性,除非您需要在特定时间范围内测试响应能力。无论哪种方式,我都不确定为什么 async 更适合单元测试......
  • Httpclient 只提供异步方法。 OP 通过在任务上调用 Result 将它们正确地转换为同步调用。严格来说,这也意味着这不是异步异常,它是在阻塞“结果”后引发的同步异常。我会尝试增加超时时间

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 完全正确!我只是假设单元测试框架与 async/await 不兼容,我使用的是 .Wait() 和 .Result。谢谢你让我直截了当!
    猜你喜欢
    • 2018-08-15
    • 2021-08-04
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    • 2011-09-11
    • 2017-02-07
    • 1970-01-01
    • 2019-08-29
    相关资源
    最近更新 更多