Retornando valor que foi passado para um método

391

Eu tenho um método em uma interface:

string DoSomething(string whatever);

Quero zombar disso com o MOQ, para que ele retorne o que foi passado - algo como:

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

Alguma ideia?

Steve Dunn
fonte

Respostas:

527

Você pode usar um lambda com um parâmetro de entrada, assim:

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

Ou um pouco mais legível:

.Returns<string>(x => x);
mhamrah
fonte
11
Parece bastante fácil até que você precisa fazer isso para um método com 7 argumentos ... Quando eu inspecionados IReturnsem Moq, ele define Returnspara 4 argumentos, no máximo . Existe uma maneira fácil de contornar isso? / Quero dizer, exceto modificar fonte Moq /
mizuki nakeshu
14
ok, é definido para até 9 argumentos na Moqv 4.0.0.0. resolvido :)
mizuki nakeshu
14
@mizukinakeshu Eu consideraria um pouco refatorador em um método de 9 argumentos, pois parece que a classe / método está fazendo muito. Talvez refatorar os 9 parâmetros em uma classe ou estrutura de configurações para ajudá-lo mais tarde?
O senador
@ TheSenator Concordo, eu ainda não lembro do que se tratava, mas acho que estava apenas hackeando alguns testes de unidade em busca de código já existente que não deveria modificar, caso contrário, esse número de argumentos definitivamente exige refatoração.
Mizuki nakeshu
27
Apenas uma observação, pois isso me confundiu: A string in .Returns<string>refere-se aos parâmetros de entrada e não aos valores que você está retornando.
Jim
241

Ainda mais útil, se você tiver vários parâmetros, poderá acessar qualquer um / todos eles com:

_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));

Você sempre precisa fazer referência a todos os argumentos, para corresponder à assinatura do método, mesmo se for usar apenas um deles.

Steve
fonte
17
Essa deve ser a resposta aceita. É exatamente isso que você precisa fazer. Qualquer outra coisa lança uma exceção "número de argumentos esperados".
Chaim Eliyah
Sim, definitivamente coloque mais fácil de ler e trabalhe ReturnsAsynctambém!
Piotr Kula
11
Esta resposta salvou o dia. Nota (futuros leitores), você pode ir um pouco mais longe também. .Returns ((string a, string b, string c) => {string d = "uau"; retorna string.Concat (a, b, c, d);});
precisa saber é o seguinte
11
Pessoalmente, esta é uma resposta muito melhor. Eu tenho muito pouco conhecimento de Moq, mas ainda assim entendi imediatamente.
Unrealsoul007
Para métodos que retornam void, usei .Callback ((string a, Exceção b, string c) => lança new Exception (b.Message));
tymtam
62

O Returns<T>método genérico pode lidar com essa situação perfeitamente.

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

Ou, se o método exigir várias entradas, especifique-as da seguinte forma:

_mock.Setup(x => x.DoSomething(It.IsAny<string>(), It.IsAny<int>())).Returns((string x, int y) => x);
WDuffy
fonte