Rückgabewert, der an eine Methode übergeben wurde

390

Ich habe eine Methode auf einer Schnittstelle:

string DoSomething(string whatever);

Ich möchte dies mit MOQ verspotten, damit es alles zurückgibt, was übergeben wurde - so etwas wie:

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

Irgendwelche Ideen?

Steve Dunn
quelle

Antworten:

526

Sie können ein Lambda mit einem Eingabeparameter verwenden, wie folgt:

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

Oder etwas besser lesbar:

.Returns<string>(x => x);
Mhamrah
quelle
1
Es scheint ganz einfach , bis Sie dies für ein Verfahren mit tun müssen , 7 Argumenten ... Als ich inspizierte IReturnsin Moq, definiert sich Returnsfür 4 Argumente höchstens . Gibt es eine einfache Möglichkeit, das zu umgehen? / Ich meine, außer Moq Quelle zu
ändern
14
ok, es ist für bis zu 9 Argumente in Moqv definiert 4.0.0.0. gelöst :)
Mizuki Nakeshu
14
@mizukinakeshu Ich würde ein bisschen wie einen Refaktor für eine 9-Argument-Methode betrachten, da es so klingt, als ob die Klasse / Methode zu viel tut. Vielleicht die 9 Parameter in eine Einstellungsklasse oder -struktur umgestalten, um Ihnen später zu helfen?
Der Senator
@TheSenator Ich stimme zu, ich rufe noch nicht wieder auf, worum es ging, aber ich glaube, ich habe nur einige Komponententests für bereits vorhandenen Code gehackt, den ich nicht ändern sollte, andernfalls erfordert diese Anzahl von Argumenten definitiv ein Refactoring.
Mizuki Nakeshu
27
Nur eine Anmerkung, die mich verwirrte: Die Zeichenfolge in .Returns<string>bezieht sich auf die Eingabeparameter und nicht auf die Werte, die Sie zurückgeben.
Jim
241

Noch nützlicher, wenn Sie mehrere Parameter haben, können Sie auf alle zugreifen:

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

Sie müssen immer auf alle Argumente verweisen, um mit der Signatur der Methode übereinzustimmen, auch wenn Sie nur eines davon verwenden.

Steve
quelle
17
Dies sollte die akzeptierte Antwort sein. Genau das müssen Sie tun. Alles andere löst eine Ausnahme "Anzahl der erwarteten Argumente" aus.
Chaim Eliyah
Ja, definitiv viel einfacher zu lesen und funktioniert ReturnsAsyncauch damit!
Piotr Kula
1
Diese Antwort hat den Tag gerettet. Hinweis (zukünftige Leser), Sie können es auch ein bisschen weiter gehen. .Returns ((String a, String b, String c) => {String d = "wow"; return string.Concat (a, b, c, d);});
GranadaCoder
1
Persönlich ist dies eine viel bessere Antwort. Ich habe sehr wenig Wissen über Moq, aber ich habe es trotzdem sofort verstanden.
unrealsoul007
Für Methoden, die void zurückgeben, habe ich .Callback ((Zeichenfolge a, Ausnahme b, Zeichenfolge c) => neue Ausnahme auslösen (b.Message)) verwendet;
Tymtam
62

Die generische Returns<T>Methode kann mit dieser Situation gut umgehen.

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

Oder wenn die Methode mehrere Eingaben erfordert, geben Sie diese wie folgt an:

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