我有 .net core weabpi (参见下面的代码)。我正在使用 polly 重试策略(请参阅下面的策略)。我想对端点(getProducts)进行单元测试并测试 polly 重试
我已经发现这些例子 https://github.com/App-vNext/Polly/wiki/Unit-testing-with-Polly---with-example但不清楚如何对端点和重试策略进行单元测试?
services
.AddHttpClient<IProductService, ProductService>()
.AddPolicyHandler(GetRetryPolicy(3, 2));
static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy(int retryCount, int breakDuration)
{
return HttpPolicyExtensions
.HandleTransientHttpError()
.OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
.WaitAndRetryAsync(retryCount, retryAttempt => TimeSpan.FromSeconds(Math.Pow(breakDuration,
retryAttempt)));
}
.Net核心API:
public interface IProductService
{
Task<IEnumerable<ProductResponse>> GetProducts(string productType);
}
public class ProductService: IProductService
{
private readonly HttpClient _httpClient;
public ProductService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<IEnumerable<ProductResponse>> GetProducts(string productType)
{
var response = await _httpClient.GetAsync("uri");
...
}
}
可悲的事实是,您无法真正对重试+端点逻辑进行单元测试,这是我的理由:
- 重试记录在顶部
HttpClient
通过 DI (AddPolicyHandler
)。当你进行单元测试时,你就是不依赖在 DI 上而不是在单个组件上。
1.1 因此,集成测试可能更适合于此。我已经详细说明了如何通过WireMock.Net https://github.com/WireMock-Net/WireMock.Net: 1 https://stackoverflow.com/a/68540520/13268855, 2 https://stackoverflow.com/a/63049086/13268855。基本思想是创建一个具有预定义响应序列的本地 http 服务器(以模拟下游系统)。
- 使用最大重试次数和时间处罚定义重试策略后,您可以not轻松检索它们。因此,从单元测试的角度来看,确实很难确保策略已正确定义(就像在seconds,不在minutes)。我已经创建了一个github问题为此 https://github.com/App-vNext/Polly/issues/756,但不幸的是V8的开发陷入了困境。
回到你的测试用例。使用给定-当时-当时结构阐明测试场景的正确方法应该像这样编写
-
Given下游服务出现故障,返回 5XX 响应
-
When我打电话给 GetProducts
-
Then执行 4 次(1 次初始 + 3 次重试)
这不是单元测试。它更像是组件/集成测试。为什么?因为即使你可以创建一个 HttpClient 模拟 https://stackoverflow.com/questions/36425008/mocking-httpclient-in-unit-tests但在那种情况下会有no重试那里的政策。
有一个解决方法:你可以通过以下方式使用策略手动装饰底层处理程序PolicyHttpMessageHandler https://stackoverflow.com/a/73036620/13268855。但这在单元测试中是一个坏主意,因为您基本上在测试中重新实现了 DI 部分。这样您就可以测试您的测试安排代码,而不是您的生产代码。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)