在啟動期間,我基本上添加了HttpClient這樣的:
services.AddHttpClient<IHttpClient, MyHttpClient>().AddPolicyHandler(GetRetryPolicy());
public IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
HttpPolicyExtensions
.HandleTransientHttpError()
.OrResult(message => message.StatusCode == HttpStatusCode.NotFound)
.WaitAndRetryAsync(GetBackOffDelay(options),
onRetry: (result, timespan, retryAttempt, context) =>
{
context.GetLogger()?.LogWarning($"Failure with status code {result.Result.StatusCode}. Retry attempt {retryAttempt}. Retrying in {timespan}.");
}));
}
如何測驗重試策略是否按預期作業?我試過寫一個這樣的測驗:
public async Task MyTest()
{
var policy = GetMockRetryPolicy(); // returns the policy shown above.
var content = HttpStatusCode.InternalServerError;
var services = new ServiceCollection();
services.AddHttpClient<IHttpClient, MyFakeClient>()
.AddPolicyHandler(policy);
var client = (MyFakeClient)services.BuildServiceProvider().GetRequiredService<IHttpClient>();
await client.Post(new Uri("https://someurl.com")), content);
// Some asserts that don't work right now
}
作為參考,這里是我的大部分Post方法MyFakeClient:
if(Enum.TryParse(content.ToString(), out HttpStatusCode statusCode))
{
if(statusCode == HttpStatusCode.InternalServerError)
{
throw new HttpResponseException(new Exception("Internal Server Error"), (int)HttpStatusCode.InternalServerError);
}
}
該MyFakeClient有一個Post方法檢查是否內容是HttpStatusCode,如果它是一個內部服務器錯誤拋出HttpResponseException。目前,這會創建正確的客戶端并觸發發布罰款。它拋出HttpResponseException但這樣做會退出測驗而不是使用重試策略。
我怎樣才能讓它在測驗中使用重試策略?
uj5u.com熱心網友回復:
問題是您無法真正對此進行單元測驗:
- 重試在
HttpClientvia DI的頂部注冊。當您進行單元測驗時,您不依賴于 DI,而是依賴于單個組件。因此,集成測驗可能更適合于此。我已經詳細說明了如何通過 WireMock.Net 做到這一點。基本思想是創建一個具有預定義回應序列的本地 http 服務器(模擬下游系統)。 - 定義重試策略(使用重試計數、時間懲罰)后,您將無法輕松檢索它們。因此,從單元測驗的角度來看,確實很難確保已正確定義策略(例如延遲以秒為單位指定,而不是以分鐘為單位)。我已經為此創建了一個github問題,但不幸的是新版本的開發已經卡住了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/370983.html
下一篇:Androidio.mockk.MockKException:找不到答案:日歷(靜態日歷#368的孩子)。getTime()
