这不是一个完全有效的解决方案,只是使问题更清晰、更具可读性的部分代码。
我在这里阅读了 Polly 的文档,但是我确实需要在 httpClient 超时后测试是否命中了以下 TimeoutPolicy 的委托(另外,如果将TimeoutPolicyonTimeoutAsync
与 RetryPolicy 一起包装 -它被命中了多少次):
public static TimeoutPolicy<HttpResponseMessage> TimeoutPolicy
{
get
{
return Policy.TimeoutAsync<HttpResponseMessage>(1, onTimeoutAsync: (context, timeSpan, task) =>
{
Console.WriteLine("Timeout delegate fired after " + timeSpan.TotalMilliseconds);
return Task.CompletedTask;
});
}
}
TimeoutPolicy 设置为 1 秒后未收到来自 HTTP 客户端的任何内容后超时(HttpClient 的模拟延迟 4 秒,如下图所示)
var httpMessageHandler = new Mock<HttpMessageHandler>();
httpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
.Callback(() => Thread.Sleep(4000))//Delayed here
.Returns(() => Task.FromResult(new HttpResponseMessage
{
StatusCode = HttpStatusCode.InternalServerError,
Content = new StringContent("Some response body", Encoding.UTF8, "text/xml")
}));
var httpClient = new HttpClient(httpMessageHandler.Object);
策略被嘲笑为能够在其上调用 .Verify() 以进行断言:
var mockedPolicies = new Mock<Policies>();
我使用模拟的 HTTP 客户端和模拟的超时策略执行调用:
await mockedPolicies.Object.TimeoutPolicy.ExecuteAsync(ct => _httpClient.PostAsync("", new StringContent("Some request body"), ct), CancellationToken.None);
断言:
mockedPolicies.Verify(p => p.TimeoutDelegate(It.IsAny<Context>(), It.IsAny<TimeSpan>(), It.IsAny<Task>()), Times.Exactly(1));
但是,测试结果显示它已被调用 0 次而不是 1 次。谢谢您的任何回答。