【问题标题】:How to wrap HttpClient for testability in C#如何在 C# 中包装 HttpClient 以实现可测试性
【发布时间】:2014-07-09 00:12:46
【问题描述】:

我正在调用一个外部 API,并且希望我的 API 可以进行单元测试。为此,我正在尝试包装 HttpClient。我现在只需要一种方法。 这是我的界面。

public interface IHttpClient
{
    Task<string> GetStringAsync(string url);
}

这就是我实现它的方式。

公共类 HttpClientWrapper : IHttpClient { 私有只读HttpClient _httpClient;

    public HttpClientWrapper()
    {
        // I could also inject this but I think this will be fine as is. 
        _httpClient = new HttpClient(new HttpClientHandler(), false);
    }

    public async Task<string> GetStringAsync(string url)
    {
        //validate url here
        return await _httpClient.GetStringAsync(url);
    }

}

我有疑问吗?这是正确的方法吗?设置 bool 参数会导致这里的资源泄漏吗?我读到了一些关于是否必须在每次调用时处理 HttpClient 的相互矛盾的想法。我接受了,不处理的一面,但不是很确定。
如果有一种方法可以在没有包装器的情况下使用 HttpClient 但使 API 可测试,那也很棒。但到目前为止,我没能成功。

谢谢, CleanKoder

【问题讨论】:

    标签: httpclient asp.net-web-api


    【解决方案1】:

    虽然为客户端创建接口仍然很好,但HttpClient 类实际上在设计时考虑了可测试性!当实例化你的HttpClient 时,你可以注入一个自定义的HttpMessageHandler。通过在此类中覆盖 Task&lt;HttpResponseMessage&gt; SendAsync(HttpRequestMessage request, CancellationToken cancellationToken),您可以在所有请求实际写入套接字之前中断所有请求,检查它们并返回您认为合适的任何内容。

    这是我在项目中编写的此类测试替身的示例,请随意修改以适应您的需求:

    public class FakeHttpMessageHandler : HttpMessageHandler
    {
        public HttpRequestMessage LastRequest;
        public string LastRequestString = string.Empty;
        public string ResponseContent = string.Empty;
        public HttpStatusCode ResponseStatusCode = HttpStatusCode.OK;
    
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
            CancellationToken cancellationToken)
        {
            if (request.Content != null)
            {
                LastRequestString = await request.Content.ReadAsStringAsync();
            }
            LastRequest = request;
            return await Task.FromResult(new HttpResponseMessage
            {
                StatusCode = ResponseStatusCode,
                Content = new StringContent(ResponseContent)
            });
        }
    }
    

    如果您认为更适合您的项目,也可以使用 NSubstitute 之类的隔离框架。

    【讨论】:

    • 你在真实代码中传递了什么? HttpMessageHandler 是抽象的。
    • 我不知道它是否是默认构造函数中使用的,但经过快速搜索我会假设msdn.microsoft.com/en-us/library/…
    猜你喜欢
    • 2021-12-01
    • 2011-02-28
    • 2021-04-21
    • 2020-04-08
    • 2022-08-07
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多