gpt4 book ai didi

httpclient - 如何在 C# 中包装 HttpClient 以实现可测试性

转载 作者:行者123 更新时间:2023-12-04 15:33:54 27 4
gpt4 key购买 nike

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

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

这就是我实现它的方式。

公共(public)类 HttpClientWrapper : IHttpClient
{
私有(private)只读 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 可测试,那也很棒。但到目前为止,我未能让它发挥作用。

谢谢,
清洁科德

最佳答案

虽然为客户端创建一个界面还是不错的,但 HttpClient类实际上是在考虑可测试性的情况下设计的!实例化您的 HttpClient 时您可以注入(inject)自定义 HttpMessageHandler .通过覆盖 Task<HttpResponseMessage> 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。

关于httpclient - 如何在 C# 中包装 HttpClient 以实现可测试性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24643523/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com