with unit tests setup mock framework and c# unit-testing asynchronous moq

c# - tests - Usar Moq para simular un método asíncrono para una prueba unitaria



verify moq (1)

Estás creando una tarea pero nunca la comienzas, por lo que nunca se completa. Sin embargo, no solo inicie la tarea, en su lugar, cambie a usar Task.FromResult<TResult> que le dará una tarea que ya se ha completado:

... .Returns(Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.OK)));

Tenga en cuenta que no estará probando la asincronía real de esta manera: si quiere hacer eso, necesita hacer un poco más de trabajo para crear una Task<T> que pueda controlar de una manera más refinada ... pero eso es algo por otro día.

También puede considerar usar un falso para IHttpClient lugar de burlarse de todo, realmente depende de la frecuencia con que lo necesite.

Estoy probando un método para un servicio que realiza una llamada a la API web. Usar un HttpClient normal funciona bien para pruebas unitarias si también ejecuto localmente el servicio web (ubicado en otro proyecto en la solución).

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 interfaz IHttpClient e implementando una versión que uso en mi aplicación. Para pruebas unitarias, hago una versión burlada completa con un método de publicación asíncrona 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 Moq en sí mismo y he estado buscando SO y google por un tiempo aprendiendo cosas nuevas, pero todavía no puedo superar este problema.

Este es 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á el método de prueba de mi 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.