Valor devuelto que se pasó a un método


391

Tengo un método en una interfaz:

string DoSomething(string whatever);

Quiero burlarme de esto con MOQ, para que devuelva lo que se haya pasado, algo como:

_mock.Setup( theObject => theObject.DoSomething( It.IsAny<string>( ) ) )
   .Returns( [the parameter that was passed] ) ;

¿Algunas ideas?

Respuestas:


527

Puede usar una lambda con un parámetro de entrada, así:

.Returns((string myval) => { return myval; });

O un poco más legible:

.Returns<string>(x => x);

1
Parece bastante fácil hasta que tenga que hacer esto por un método con 7 argumentos ... Cuando inspeccioné IReturnsen Moq, se define Returnspor 4 argumentos como máximo . ¿Alguna forma fácil de evitar eso? / Quiero decir, excepto modificar la fuente de Moq /
mizuki nakeshu

14
ok, está definido para hasta 9 argumentos en Moqv 4.0.0.0. resuelto :)
mizuki nakeshu

14
@mizukinakeshu Consideraría un poco refactorizador en un método de 9 argumentos, ya que parece que la clase / método está haciendo demasiado. ¿Quizás refactorice los 9 parámetros en una clase o estructura de configuración para ayudarlo más tarde?
El senador

@TheSenator De acuerdo, no recuerdo de qué se trataba, pero supongo que solo estaba hackeando algunas pruebas unitarias para el código ya existente que no debía modificar, de lo contrario, este número de argumentos definitivamente requiere una refactorización.
mizuki nakeshu

27
Solo una nota ya que esto me confundió: la cadena de .Returns<string>entrada se refiere a los parámetros de entrada y no a los valores que está devolviendo.
Jim

241

Aún más útil, si tiene múltiples parámetros, puede acceder a cualquiera / a todos ellos con:

_mock.Setup(x => x.DoSomething(It.IsAny<string>(),It.IsAny<string>(),It.IsAny<string>())
     .Returns((string a, string b, string c) => string.Concat(a,b,c));

Siempre debe hacer referencia a todos los argumentos, para que coincida con la firma del método, incluso si solo va a usar uno de ellos.


17
Esta debería ser la respuesta aceptada. Esto es exactamente lo que necesitas hacer. Cualquier otra cosa arroja una excepción de "número de argumentos esperados".
Chaim Eliyah

Sí, definitivamente es mucho más fácil de leer y funciona ReturnsAsynctambién.
Piotr Kula

1
Esta respuesta salvó el día. Nota (futuros lectores), también puedes llevarlo un poco más lejos. .Returns ((string a, string b, string c) => {string d = "wow"; return string.Concat (a, b, c, d);});
granadaCoder

1
Personalmente, esta es una respuesta mucho mejor. Tengo muy poco conocimiento de Moq pero aún así lo entendí de inmediato.
unrealsoul007

Para los métodos que devuelven void, utilicé .Callback ((string a, Exception b, string c) => throw new Exception (b.Message));
tymtam

62

El Returns<T>método genérico puede manejar esta situación muy bien.

_mock.Setup(x => x.DoSomething(It.IsAny<string>())).Returns<string>(x => x);

O si el método requiere múltiples entradas, especifíquelas así:

_mock.Setup(x => x.DoSomething(It.IsAny<string>(), It.IsAny<int>())).Returns((string x, int y) => x);
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.