c# - quiere - ¿Cómo puedo decirle a Moq que devuelva una tarea?
moq que significa (4)
Tengo una interfaz que declara
Task DoSomethingAsync();
Estoy usando MoqFramework para mis pruebas:
[TestMethod()]
public async Task MyAsyncTest()
{
Mock<ISomeInterface> mock = new Mock<ISomeInterface>();
mock.Setup(arg => arg.DoSomethingAsync()).Callback(() => { <my code here> });
...
}
Luego en mi prueba ejecuto el código que invoca a la await DoSomethingAsync()
. Y la prueba simplemente falla en esa línea. ¿Qué estoy haciendo mal?
Ahora también puede usar el paquete Talentsoft.Moq.SetupAsync https://github.com/TalentSoft/Moq.SetupAsync
En la base de las respuestas encontradas aquí y las ideas propuestas a Moq pero aún no implementadas aquí: https://github.com/moq/moq4/issues/384 , simplifica enormemente la configuración de los métodos asíncronos
Pocos ejemplos encontrados en respuestas anteriores realizadas con la extensión SetupAsync:
mock.SetupAsync(arg=>arg.DoSomethingAsync());
mock.SetupAsync(arg=>arg.DoSomethingAsync()).Callback(() => { <my code here> });
mock.SetupAsync(arg=>arg.DoSomethingAsync()).Throws(new InvalidOperationException());
Solo necesita agregar .Returns(Task.FromResult(0));
después de la devolución de llamada.
Ejemplo:
mock.Setup(arg => arg.DoSomethingAsync())
.Callback(() => { <my code here> })
.Returns(Task.FromResult(0));
Su método no tiene devoluciones de llamada, por lo que no hay razón para usar .CallBack()
. Simplemente puede devolver una Tarea con los valores deseados utilizando .Returns()
y Task.FromResult , por ejemplo:
MyType someValue=...;
mock.Setup(arg=>arg.DoSomethingAsync())
.Returns(Task.FromResult(someValue));
Actualización 2014-06-22
Moq 4.2 tiene dos nuevos métodos de extensión para ayudar con esto.
mock.Setup(arg=>arg.DoSomethingAsync())
.ReturnsAsync(someValue);
mock.Setup(arg=>arg.DoSomethingAsync())
.ThrowsAsync(new InvalidOperationException());
Actualización 2016-05-05
Como menciona Seth Flowers en la otra respuesta , ReturnsAsync
solo está disponible para los métodos que devuelven una Task<T>
. Para los métodos que devuelven sólo una tarea,
.Returns(Task.FromResult(default(object)))
puede ser usado.
Como se muestra en esta respuesta , en .NET 4.6 esto se simplifica a .Returns(Task.CompletedTask);
, p.ej:
mock.Setup(arg=>arg.DoSomethingAsync())
.Returns(Task.CompletedTask);
Problema similar
Tengo una interfaz que se parecía aproximadamente a:
Task DoSomething(int arg);
Los síntomas
Mi prueba de unidad falló cuando mi servicio bajo prueba awaited
la llamada a DoSomething
.
Fijar
A diferencia de la respuesta aceptada, no puede llamar a .ReturnsAsync()
en su Setup()
de este método en este escenario, porque el método devuelve la Task
no genérica, en lugar de la Task<T>
.
Sin embargo, aún puede usar .Returns(Task.FromResult(default(object)))
en la configuración, lo que permite que la prueba pase.