如何在 C# 中包装 HttpClient 以实现可测试性
Posted
技术标签:
【中文标题】如何在 C# 中包装 HttpClient 以实现可测试性【英文标题】:How to wrap HttpClient for testability in C# 【发布时间】: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
【问题讨论】:
【参考方案1】:虽然为客户端创建接口仍然很好,但HttpClient
类实际上在设计时考虑了可测试性!当实例化你的HttpClient
时,你可以注入一个自定义的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 之类的隔离框架。
【讨论】:
你在真实代码中传递了什么? HttpMessageHandler 是抽象的。 我不知道它是否是默认构造函数中使用的,但经过快速搜索我会假设msdn.microsoft.com/en-us/library/…以上是关于如何在 C# 中包装 HttpClient 以实现可测试性的主要内容,如果未能解决你的问题,请参考以下文章
如何在 AppBar 中包装子小部件以获得更大的子高度和 Flutter 中的填充
如何使用 .Net 4.0 中包含的 HttpClient 类将文件上传到在 IIS Express 中运行的 Asp.Net MVC 4.0 操作