[英]retry polly unit testing (xunit and moq)
我有 .net 核心 weabpi(见下面的代码)。 我正在使用 polly 重试策略(请参阅下面的策略)。 我想对端点(getProducts)进行单元测试并测试 polly 重试
我找到了这些示例,但不清楚如何对端点进行单元测试和重试策略?
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");
...
}
}
第一的
我建议您在策略中添加带有抖动退避的等待和重试。
像这样的东西:
var delay = Backoff.DecorrelatedJitterBackoffV2(medianFirstRetryDelay: TimeSpan.FromMilliseconds(100), policyRetryCount);
RetryPolicy retryPolicy = Policy
.Handle<YourException>()
.WaitAndRetry(delay);
然后,只需Mock
您的服务并对其进行测试,例如:
Mock<IProductService> mockedProductService = new Mock<IProductService>();
mockedProductService.Setup(service => service.GetProducts(productType))
.ThrowsYourException();
var result = yourTestingMehtod
Assert.IsNotNull(result);
mockedProductService.Verify(service => service.GetProducts(productType), Times.Exactly(expectedServiceCall));
// example, expectedServiceCall is when you set retryCount 3, it will be 4
更新
我想您正在调用您的服务,例如:
retryPolicy.Execute(() => productService.GetProducts())
可悲的事实是,您无法真正对重试+端点逻辑进行单元测试,这是我的理由:
AddPolicyHandler
) 在HttpClient
的顶部注册。 当您进行单元测试时,您不依赖于 DI,而是依赖于单个组件。回到你的测试用例。 用 given-when-then 结构表达测试场景的正确方法应该这样写
这不是单元测试。 它更像是一个组件/集成测试。 为什么? 因为即使您可以创建一个 HttpClient 模拟,但在这种情况下,那里不会有重试策略。
有一个解决方法:您可以通过PolicyHttpMessageHandler
使用策略手动装饰底层处理程序。 但这在单元测试中是个坏主意,因为您基本上在测试中重新实现了 DI 部分。 这样,您将测试您的测试安排代码,而不是您的生产代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.