Usando Moq y miré Callback
pero no he podido encontrar un ejemplo simple para entender cómo usarlo.¿Puede ayudarme a entender la devolución de llamada Moq?
¿Tiene un pequeño fragmento de trabajo que explique claramente cómo y cuándo usarlo?
Usando Moq y miré Callback
pero no he podido encontrar un ejemplo simple para entender cómo usarlo.¿Puede ayudarme a entender la devolución de llamada Moq?
¿Tiene un pequeño fragmento de trabajo que explique claramente cómo y cuándo usarlo?
difícil de superar https://github.com/Moq/moq4/wiki/Quickstart
Si eso no es lo suficientemente claro, yo lo llamaría un error doc ...
EDIT: En respuesta a su aclaración ...
Para cada burlado Setup
método de llevar a cabo, se llega a indicar cosas como:
El mecanismo .Callback
dice: "No puedo describirlo en este momento, pero cuando una forma llamada esto sucede, llámame y haré lo que sea necesario ". Como parte de la misma cadena de llamadas fluidas, puede controlar el resultado para devolver (si corresponde) a través del .Returns
". En los ejemplos de QS, un ejemplo es que hacen que el valor que se devuelve aumente cada vez.
En general , no necesitará un mecanismo como este muy a menudo (xUnit Test Patterns tiene términos para los antipatrones de las pruebas de lógica condicional de la clase ilk), y si hay alguna manera más simple o integrada de establecer lo que necesita, debe usarse en preferencia.
Part 3 of 4 in Justin Etheredge's Moq series lo cubre, y there's another example of callbacks here
He aquí un ejemplo del uso de una devolución de llamada para poner a prueba una entidad enviado a un servicio de datos que maneja una insertar.
var mock = new Mock<IDataService>();
DataEntity insertedEntity = null;
mock.Setup(x => x.Insert(It.IsAny<DataEntity>())).Returns(1)
.Callback((DataEntity de) => insertedEntity = de);
Sintaxis alternativa método genérico:
mock.Setup(x => x.Insert(It.IsAny<DataEntity>())).Returns(1)
.Callback<DataEntity>(de => insertedEntity = de);
A continuación, se puede probar algo así como
Assert.AreEqual("test", insertedEntity.Description, "Wrong Description");
Podría decirse que para ese caso en particular (dependiendo de si está tratando de expresar las pruebas contra el estado o el comportamiento), en algunos casos puede ser más limpio utilizar un 'It.Is
En la parte superior de las otras buenas respuestas aquí, yo he utilizado para realizar la lógica antes lanzando una excepción. Por ejemplo, necesitaba almacenar todos los objetos que se pasaron a un método para su posterior verificación, y ese método (en algunos casos de prueba) necesitó arrojar una excepción. Llamar al .Throws(...)
en Mock.Setup(...)
anula la acción Callback()
y nunca la llama. Sin embargo, al lanzar una excepción dentro de la Devolución de llamada, aún puede hacer todas las cosas buenas que una devolución de llamada tiene para ofrecer, y aun lanzar una excepción.
Hay dos tipos de Callback
en moq. Uno sucede antes de que regrese la llamada; el otro sucede después de que la llamada vuelve.
var message = "";
mock.Setup(foo => foo.Execute(arg1: "ping", arg2: "pong"))
.Callback((x, y) =>
{
message = "Rally on!";
Console.WriteLine($"args before returns {x} {y}");
})
.Returns(message) // Rally on!
.Callback((x, y) =>
{
message = "Rally over!";
Console.WriteLine("arg after returns {x} {y}");
});
En ambos devoluciones de llamada, podemos:
En realidad, ambos suceden antes de que regrese la llamada (en lo que respecta a la persona que llama). Ver https://stackoverflow.com/a/28727099/67824. –
Callback
es simplemente un medio para ejecutar cualquier costumbre código que desea cuando se realiza una llamada a uno de los métodos de prueba. Aquí hay un ejemplo simple:
public interface IFoo
{
int Bar(bool b);
}
var mock = new Mock<IFoo>();
mock.Setup(mc => mc.Bar(It.IsAny<bool>()))
.Callback<bool>(b => Console.WriteLine("Bar called with: " + b))
.Returns(42);
var ret = mock.Object.Bar(true);
Console.WriteLine("Result: " + ret);
// output:
// Bar called with: True
// Result: 42
Recientemente me encontré con un caso de uso interesante para él. Supongamos que espera algunas llamadas a su simulacro, pero suceden al mismo tiempo. Por lo tanto, no tiene forma de saber el orden en el que los llamarán, pero desea saber si las llamadas que esperaba tuvieron lugar (independientemente de la orden). Se puede hacer algo como esto:
var cq = new ConcurrentQueue<bool>();
mock.Setup(f => f.Bar(It.IsAny<bool>())).Callback<bool>(cq.Enqueue);
Parallel.Invoke(() => mock.Object.Bar(true),() => mock.Object.Bar(false));
Console.WriteLine("Invocations: " + String.Join(", ", cq));
// output:
// Invocations: True, False
Por cierto no se deje confundir por la engañosa "antes Returns
" y "después Returns
" distinción. Es meramente una distinción técnica de si su código personalizado se ejecutará después de que se haya evaluado Returns
o antes. A los ojos de quien llama, ambos se ejecutarán antes de que se devuelva el valor. De hecho, si el método es void
-retorno no puede llamar al Returns
y, sin embargo, funciona igual. Para obtener más información, consulte https://stackoverflow.com/a/28727099/67824.
se olvidó de mencionar. Por supuesto que he visto su ejemplo, pero por alguna razón todavía no está claro para mí. avergonzado por decir, pero es cierto. – user9969
¿Tal vez dar un ejemplo de código donde crees que lo necesitas y alguien puede conectar los puntos? –
Hola Ruben Estoy aprendiendo Moq y si quieres estoy construyendo muchos ejemplos para entender cómo usarlo. Mi problema es que no entiendo cuándo usarlo. Una vez que entiendo el problema resuelto, escribiré mi propio código. Si tuvieras que explicarlo en tu propia palabra, ¿cuándo utilizarías la devolución de llamada? gracias aprecio su tiempo – user9969