¿Cómo puedo probar una política de reintento de Polly que está configurada durante el inicio?
Durante el inicio, básicamente agrego un HttpClient
así:
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($"Error con código de estado {result.Result.StatusCode}. Intento de reintentar {retryAttempt}. Reintentando en {timespan}.");
}));
}
¿Cómo puedo probar que la política de reintento funciona como se espera? He intentado escribir una prueba como esta:
public async Task MyTest()
{
var policy = GetMockRetryPolicy(); // devuelve la política mostrada anteriormente.
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);
// Algunas afirmaciones que no funcionan en este momento
}
Para referencia, aquí está la mayor parte de mi método Post
en MyFakeClient
:
if(Enum.TryParse(content.ToString(), out HttpStatusCode statusCode))
{
if(statusCode == HttpStatusCode.InternalServerError)
{
throw new HttpResponseException(new Exception("Error interno del servidor"), (int)HttpStatusCode.InternalServerError);
}
}
El MyFakeClient
tiene un método Post
que comprueba si el contenido es un HttpStatusCode
y si es un error interno del servidor, lanza una excepción HttpResponseException
. En este momento, esto crea el cliente correcto y desencadena la publicación correctamente. Lanza la HttpResponseException
, pero al hacerlo sale de la prueba en lugar de usar la política de reintento.
¿Cómo puedo hacer que use la política de reintento en la prueba?
davy.ai
Para probar que la política de reintento funcione como se espera, podría probar lo siguiente:
DelegatingHandler
y anular el métodoSendAsync
para devolver una respuesta con el código de estado deseado (por ejemplo,HttpStatusCode.InternalServerError
) para las primeras X solicitudes (donde X es el número de reintentos que desea probar), y luego devolver una respuesta exitosa para solicitudes posteriores. Esto simulará el comportamiento de error transitorio que la política de reintento debe manejar.En su método de prueba, cree un HttpClient con el controlador de delegación de prueba y páselo a su implementación de
MyHttpClient
. Luego, llame al métodoPost
y asegúrese de que reintente el número correcto de veces y eventualmente tenga éxito. Puede usar una biblioteca comoFluentAssertions
para hacer que sus afirmaciones sean más legibles.Código de prueba de ejemplo (usando
NUnit
yFluentAssertions
):Tenga en cuenta que este enfoque implica una prueba de integración en lugar de una prueba de unidad, ya que requiere una instancia real de HttpClient y conectividad de red. Sin embargo, proporciona una simulación más precisa del comportamiento de HttpClient y le permite probar la política de reintento sin depender de detalles de implementación de HttpClient en sí.