Retour de la valeur transmise à une méthode

391

J'ai une méthode sur une interface:

string DoSomething(string whatever);

Je veux me moquer de cela avec MOQ, afin qu'il renvoie tout ce qui a été passé - quelque chose comme:

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

Des idées?

Steve Dunn
la source

Réponses:

527

Vous pouvez utiliser un lambda avec un paramètre d'entrée, comme ceci:

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

Ou un peu plus lisible:

.Returns<string>(x => x);
mhamrah
la source
1
Semble assez facile jusqu'à ce que vous ayez besoin de le faire pour une méthode avec 7 arguments ... Quand j'ai inspecté IReturnsdans Moq, il définit Returnspour 4 arguments au maximum . Un moyen facile de contourner cela? / Je veux dire, sauf la modification de la source Moq /
mizuki nakeshu
14
ok, il est défini pour un maximum de 9 arguments dans Moqv 4.0.0.0. résolu :)
mizuki nakeshu
14
@mizukinakeshu Je considérerais un peu un refactor sur une méthode à 9 arguments car il semble que la classe / méthode en fait trop. Peut-être refactoriser les 9 paramètres dans une classe de paramètres ou une structure pour vous aider plus tard?
Le sénateur
@TheSenator D'accord, je ne rappelle pas déjà de quoi il s'agissait, mais je suppose que je piratais ensemble des tests unitaires pour du code déjà existant que je ne devais pas modifier, sinon ce nombre d'arguments appelle définitivement une refactorisation.
mizuki nakeshu
27
Juste une note car cela m'a dérouté: la chaîne en .Returns<string>fait référence au (x) paramètre (s) d'entrée et non aux valeurs que vous retournez.
Jim
241

Encore plus utile, si vous avez plusieurs paramètres, vous pouvez accéder à chacun d'entre eux avec:

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

Vous devez toujours référencer tous les arguments, pour correspondre à la signature de la méthode, même si vous n'utilisez qu'un seul d'entre eux.

Steve
la source
17
Ce devrait être la réponse acceptée. C'est exactement ce que vous devez faire. Tout autre élément lève une exception "nombre d'arguments attendus".
Chaim Eliyah
Oui, certainement plus facile à lire et fonctionne ReturnsAsyncaussi!
Piotr Kula
1
Cette réponse a sauvé la mise. Remarque (futurs lecteurs), vous pouvez aussi aller un peu plus loin. .Returns ((chaîne a, chaîne b, chaîne c) => {chaîne d = "wow"; retourne chaîne.Concat (a, b, c, d);});
granadaCoder
1
Personnellement, c'est une bien meilleure réponse. Je connais très peu Moq mais je l'ai tout de suite compris.
unrealsoul007
Pour les méthodes renvoyant void, j'ai utilisé .Callback ((chaîne a, exception b, chaîne c) => lancer une nouvelle exception (b.Message));
tymtam
62

La Returns<T>méthode générique peut très bien gérer cette situation.

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

Ou si la méthode nécessite plusieurs entrées, spécifiez-les comme suit:

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