2011-05-23 21 views
18

¿Qué puede hacer que It.IsAny<string>() devuelva nulo en cada llamada? ¿Soy incorrecto al asumir que está diseñado para devolver una cadena no nula?Moq - It.IsAny <string>() siempre devuelve nulo

Aquí está el uso - donde el método de inicio de sesión arroja una ArgumentNullException para un segundo argumento nulo (cadena de conexión). Asumí que It.IsAny<string>() proporcionaría una cadena no nula, que omitiría la ArgumentNullException.

var mockApiHelper = new Mock<ApiHelper>(); 
mockApiHelper.Setup(m => m.Connect(It.IsAny<string>(), 
            It.IsAny<string>(), 
            It.IsAny<string>())); 

var repositoryPlugin = new RepositoryPlugin(mockApiHelper.Object); 
repositoryPlugin.Login(new CredentialsInfo(), It.IsAny<string>()); 

Assert.IsTrue(repositoryPlugin.LoggedIn, 
    "LoggedIn property should be true after the user logs in."); 

Respuesta

24

Bueno, It.IsAny<TValue> simplemente devuelve el resultado de la llamada Match<TValue>.Create - que a su vez vuelve default(TValue). Eso será nulo para cualquier tipo de referencia.

No está claro si realmente está llamando al objeto correcto, ¿no debería llamarlo en el simulacro en lugar del código real?

Todas las muestras que he visto usan It.IsAny en el contexto de una llamada mock.Setup. ¿Podría dar más información sobre cómo está tratando de usarlo?

+0

Ah, ya veo. He agregado la prueba completa a la pregunta. Lo estoy usando tanto para mi simulacro, como para un objeto real. Pero parece que no está destinado para su uso con objetos reales. – Jeremy

+1

@Jeremy: No, la idea es que transfiera valores reales (bueno, valores de muestra) a su código real. 'It.IsAny' está destinado a validar los valores pasados ​​* de * su código real a sus simulacros. –

+0

Lo tengo, así que lo he estado pensando como una técnica de generación de datos ... pero no es para eso. ¡Gracias! – Jeremy

2

It.IsAny se utiliza para que coincida con el código en su Returns() y Callback() que controla lo que se empuja en sus pruebas.

10

No, It.IsAny se usa para especificar en su programa de instalación que CUALQUIER secuencia pasada será igual. Puede hacer su configuración de modo que si su método se llama solo con una cadena en particular, volverá. Considere esto:

myMock.Setup(x => x.DoSomething(It.IsAny<string>()).Return(123); 
myMock.Setup(x => x.DoSomething("SpecialString").Return(456); 

Lo que está utilizando el simulacro A continuación, obtener valores diferentes en función del parámetro se pasa la maqueta cuando se invoca HacerAlgo. Puede hacer lo mismo al verificar las llamadas a los métodos:

myMock.Verify(x => x.DoSomething(It.IsAny<string>())); // As long as DoSomething was called, this will be fine. 
myMock.Verify(x => x.DoSomething("SpecialString")); // DoSomething MUST have been called with "SpecialString" 

Además, veo que editó su pregunta. En lugar de:

Assert.IsTrue(repositoryPlugin.LoggedIn, "LoggedIn property should be true after the user logs in."); 

hacer esto:

mockApiHelper.Verify(x => x.Connect(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()), Times.Once()); // Change times to whatever you expect. If you expect particular values, replace the relevent It.IsAny<string() calls with those actual vaules. 
Cuestiones relacionadas