Estoy probando un método para un servicio que realiza una API
llamada web . Usar un normal HttpClient
funciona bien para pruebas unitarias si también ejecuto el servicio web (ubicado en otro proyecto en la solución) localmente.
Sin embargo, cuando reviso mis cambios, el servidor de compilación no tendrá acceso al servicio web, por lo que las pruebas fallarán.
He ideado una forma de evitar esto para mis pruebas unitarias creando una IHttpClient
interfaz e implementando una versión que uso en mi aplicación. Para las pruebas unitarias, realizo una versión simulada completa con un método de publicación asincrónica simulada. Aquí es donde me he encontrado con problemas. Quiero devolver un OK HttpStatusResult
para esta prueba en particular. Para otra prueba similar, devolveré un mal resultado.
La prueba se ejecutará pero nunca se completará. Se cuelga a la espera. Soy nuevo en la programación asincrónica, los delegados y el propio Moq y he estado buscando SO y google durante un tiempo aprendiendo cosas nuevas, pero todavía parece que no puedo superar este problema.
Aquí está el método que estoy tratando de probar:
public async Task<bool> QueueNotificationAsync(IHttpClient client, Email email)
{
// do stuff
try
{
// The test hangs here, never returning
HttpResponseMessage response = await client.PostAsync(uri, content);
// more logic here
}
// more stuff
}
Aquí está mi método de prueba de unidad:
[TestMethod]
public async Task QueueNotificationAsync_Completes_With_ValidEmail()
{
Email email = new Email()
{
FromAddress = "[email protected]",
ToAddress = "[email protected]",
CCAddress = "[email protected]",
BCCAddress = "[email protected]",
Subject = "Hello",
Body = "Hello World."
};
var mockClient = new Mock<IHttpClient>();
mockClient.Setup(c => c.PostAsync(
It.IsAny<Uri>(),
It.IsAny<HttpContent>()
)).Returns(() => new Task<HttpResponseMessage>(() => new HttpResponseMessage(System.Net.HttpStatusCode.OK)));
bool result = await _notificationRequestService.QueueNotificationAsync(mockClient.Object, email);
Assert.IsTrue(result, "Queue failed.");
}
¿Qué estoy haciendo mal?
Gracias por tu ayuda.
fuente
ReturnsAysnc
, que hace exactamente esto.Recomiende la respuesta de @Stuart Grassie arriba.
fuente
Con
Mock.Of<...>(...)
forasync
method puedes usarTask.FromResult(...)
:fuente