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?

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

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.


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);
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.