servicios metodo ejemplos definicion con c# moq

c# - metodo - servicios de ti ejemplos



¿Cuál es la diferencia entre pasar It.IsAny<int>() y el valor de It.IsAny<int>() a una configuración de método (2)

It.IsAny<int>() tiene un tipo de retorno de int y devuelve 0 , por lo que su segunda configuración es equivalente a:

mock.Setup(x => x.Bar2(0)).Returns(true);

No verifiqué el código moq, pero estoy bastante seguro de que cuando evalúa la expresión en el método de configuración, toma en cuenta que el parámetro es en realidad It.IsAny contra un número normal.

Usted está mejor si crea las configuraciones directamente en sus métodos de ayuda, y no pasa It.IsAny.

Estoy usando Moq y quiero crear clases de constructor para crear mis simulacros con valores predeterminados razonables predeterminados que se pueden anular durante la configuración de la prueba según sea necesario. El enfoque que tomé usa métodos de extensión en los que paso valores de parámetros de entrada y salida esperada. Al hacerlo, veo un comportamiento diferente en lo que me parece ser un código semánticamente equivalente: pasar It.IsAny () directamente en una configuración frente a pasar el valor de It.IsAny () indirectamente en una configuración. Ejemplo:

public interface IFoo { bool Bar(int value); bool Bar2(int value); } public class Foo : IFoo { public bool Bar(int value) { return false; } public bool Bar2(int value) { return false; } } var mock = new Mock<IFoo>(); mock.Setup(x => x.Bar(It.IsAny<int>())).Returns(true); Assert.IsTrue(mock.Object.Bar(123)); // Succeeds var myValue = It.IsAny<int>(); mock.Setup(x => x.Bar2(myValue)).Returns(true); Assert.IsTrue(mock.Object.Bar2(123)); // Fails

Ambas llamadas son equivalentes (para mí), pero la llamada a Bar2 falla en la aserción. ¿Por qué es esto?


It.IsAny solo permite que Moq coincida con futuras invocaciones de llamadas a métodos si se usa dentro del constructo de Setup . Cuando se llama Setup Moq simplemente agrega la llamada al método a su caché de las llamadas al método ya establecido. Tenga en cuenta que el argumento de Setup en su ejemplo tiene el tipo Expression<Func<IFoo, bool>> . Dado que está pasando una Expression , la llamada al método real no se invoca y Moq tiene la capacidad de atravesar la expresión para determinar qué parámetros de la llamada al método fueron explícitos y cuáles son los argumentos de It.IsAny . Utiliza esta capacidad para determinar si una futura llamada de método en tiempo de ejecución coincide con una de las llamadas de método ya configuradas.

Para que el método Bar pueda aceptar el argumento It.IsAny<int>() , es necesario que It.IsAny<int>() devuelva un int (ya que ese es el tipo del parámetro de Bar ) . En general, el tipo de retorno de It.IsAny<T> debe ser T Un valor arbitrario de T debe ser elegido. La opción más natural es la default(T) , que funciona para los tipos de referencia y los tipos de valor. (Lea más sobre la palabra clave predeterminada here ). En su caso, eso es default(int) , que es 0 .

Entonces, cuando realmente It.IsAny<int>() el valor de 0 se devuelve inmediatamente. Sin embargo, cuando usa It.IsAny<int>() en una Expression (como en el argumento del método de Setup ), entonces la estructura de árbol de la llamada del método se conserva y Moq puede hacer coincidir las futuras invocaciones del método con la llamada del método encapsulada por La Expression .

Entonces, aunque no puede mantenerlo como una variable de ninguna manera significativa, puede mantener la Expression completa en una variable:

Expression<Func<IFoo, bool>> myExpr = x => x.Bar2(It.IsAny<int>()); mock.Setup(myExpr).Returns(true); Assert.IsTrue(mock.Object.Bar2(123));

Finalmente, solo quiero recordarles que Moq es de código abierto. La fuente está disponible here . Me parece valioso tener ese código fuente para poder hacer clic y explorar el código y las pruebas unitarias.