C# 为集成测试创建默认HttpClientFactory
我有一个类型化客户端,我想注册为singleton:C# 为集成测试创建默认HttpClientFactory,c#,asp.net-core,.net-core,dotnet-httpclient,httpclientfactory,C#,Asp.net Core,.net Core,Dotnet Httpclient,Httpclientfactory,我有一个类型化客户端,我想注册为singleton: public class SomeHttpClient { private readonly IHttpClientFactory _clientFactory; public SomeHttpClient(IHttpClientFactory clientFactory) { _clientFactory = clientFactory; } public Task MakeSom
public class SomeHttpClient
{
private readonly IHttpClientFactory _clientFactory;
public SomeHttpClient(IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
}
public Task MakeSomeCallAsync(...)
{
var client = _clientFactory.Create();
// Do more stuff
}
}
类型化客户机必须是单例客户机,因为它有一些断路器逻辑,如果API对客户机进行速率限制,则会断开电路。电路必须在整个应用程序中断开,显然不仅仅是当前的请求管道(否则客户端将继续访问API,而API已经受到其他实例的速率限制)。这已经通过使用封装该功能的类型化客户端实现了(但不是Polly)
现在,由于类型化客户端将是一个单例客户端,我们不能注入单个HttpClient
,因为这将带来我们以前在单个长寿HttpClient
上遇到的所有问题。显而易见的解决方案是注入一个HttpClientFactory
,现在每当类型化的客户端需要一个HttpClient
实例时,就可以使用该实例来发出一个HttpClientFactory
实例,而不必担心生命周期管理等问题,因为这已经推迟到HttpClientFactory
了
我现在的问题是如何为一个简单的功能集成测试创建一个默认的HttpClientFactory
,在这个测试中,我想实例化一个类型化的客户机,看看我是否可以点击API并从一个自动测试中获得成功的响应
我不想设置一个ASP.NET核心测试服务器和围绕它的整个应用程序,因为这对于我现在想做的那种功能测试来说是一种过分的做法
没有公共构造函数可用于注入
HttpClientFactory
?我只是自己创建了一个用于测试的构造函数(我想可能已经有一种方法可以为我做到这一点):
我现在的问题是如何为一个简单的功能集成测试创建一个默认的HttpClientFactory,在这个测试中,我想实例化一个类型化的客户机,看看我是否可以点击API并从一个自动测试中获得成功的响应
您的测试可以获取用于在启动
中配置HttpClientFactory的确切代码(这是一个使用Polly策略的示例,但它可以是HttpClientFactory上的任何配置)
第[2]行可能是启动
类中的确切代码。您可以将它从正常的ConfigureServices(…)
方法中分离出来,转换为一个单独的static
方法,您的测试也可以调用该方法-因此,您的测试可以准确地测试StartUp
配置的内容
然后在测试中:
IHttpClientFactory factory = services
.BuildServiceProvider()
.GetRequiredService<IHttpClientFactory>();
var sut = new SomeHttpClient(factory);
IHttpClientFactory=服务
.BuildServiceProvider()
.GetRequiredService();
var sut=新的某个HttpClient(工厂);
,但使用C#
或者更好的方法是使用单例:
public sealed class DefaultHttpClientFactory : IHttpClientFactory
{
private static readonly Lazy<HttpClient> _httpClientLazy =
new Lazy<HttpClient>(() => new HttpClient());
// NOTE: This will always return the same HttpClient instance.
public HttpClient CreateClient(string name) => _httpClientLazy.Value;
}
公共密封类DefaultHttpClientFactory:IHttpClientFactory
{
私有静态只读惰性\u httpClientLazy=
新的惰性(()=>newhttpclient());
//注意:这将始终返回相同的HttpClient实例。
公共HttpClient CreateClient(字符串名称)=>\u httpClientLazy.Value;
}
拜托,F#是个骗子!与C#verbosity=)相比,这是一个很好的答案(如果您转换回C#),因为我实际上希望在集成测试中发送数据。使用此方法,您可以完全控制。很不错的!
IHttpClientFactory factory = services
.BuildServiceProvider()
.GetRequiredService<IHttpClientFactory>();
var sut = new SomeHttpClient(factory);
public sealed class DefaultHttpClientFactory : IHttpClientFactory
{
public HttpClient CreateClient(string name) => new HttpClient();
}
public sealed class DefaultHttpClientFactory : IHttpClientFactory
{
private static readonly Lazy<HttpClient> _httpClientLazy =
new Lazy<HttpClient>(() => new HttpClient());
// NOTE: This will always return the same HttpClient instance.
public HttpClient CreateClient(string name) => _httpClientLazy.Value;
}