Zwracana wartość, która została przekazana do metody

390

Mam metodę interfejsu:

string DoSomething(string whatever);

Chcę się z tego wyśmiewać za pomocą MOQ, aby zwracało to, co zostało przekazane - coś w stylu:

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

Jakieś pomysły?

Steve Dunn
źródło

Odpowiedzi:

525

Możesz użyć lambda z parametrem wejściowym, na przykład:

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

Lub nieco bardziej czytelny:

.Returns<string>(x => x);
mhamrah
źródło
1
Wydaje się dość proste, dopóki nie trzeba to zrobić za pomocą metody z 7 argumentów ... Kiedy kontrolowane IReturnsw Min definiuje Returnsdla 4 argumenty co najwyżej . Jakiś prosty sposób obejść ten problem? / Mam na myśli oprócz modyfikowania źródła Moq /
mizuki nakeshu
14
ok, jest zdefiniowany dla maksymalnie 9 argumentów w Moqv 4.0.0.0. rozwiązane :)
mizuki nakeshu
14
@mizukinakeshu Zastanowiłbym się nad refaktorem metody 9-argumentowej, ponieważ wydaje się, że klasa / metoda robi zbyt wiele. Być może przekształciłeś 9 parametrów w klasę ustawień lub strukturę, aby ci pomóc później?
Senator
@ TheSenator Zgadzam się, jeszcze nie przypominam sobie o co chodziło, ale chyba właśnie zhakowałem kilka testów jednostkowych dla już istniejącego kodu, którego nie miałem modyfikować, w przeciwnym razie ta liczba argumentów zdecydowanie wymaga refaktoryzacji.
mizuki nakeshu
27
Tylko uwaga, która mnie pomyliła: ciąg w .Returns<string>odnosi się do parametrów wejściowych, a nie do wartości, które zwracasz.
Jim
241

Nawet bardziej przydatne, jeśli masz wiele parametrów, możesz uzyskać dostęp do dowolnego / wszystkich z nich za pomocą:

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

Zawsze musisz odwoływać się do wszystkich argumentów, aby dopasować podpis metody, nawet jeśli zamierzasz użyć tylko jednego z nich.

Steve
źródło
17
To powinna być zaakceptowana odpowiedź. Właśnie to musisz zrobić. Wszystko inne generuje wyjątek „liczba oczekiwanych argumentów”.
Chaim Eliyah
Tak, zdecydowanie łatwiej jest je czytać i ReturnsAsyncteż z nimi współpracuje !
Piotr Kula
1
Ta odpowiedź uratowała dzień. Uwaga (przyszli czytelnicy), możesz pójść o krok dalej. .Returns ((ciąg a, ciąg b, ciąg c) => {ciąg d = "wow"; zwraca ciąg.Concat (a, b, c, d);});
granadaCoder,
1
Osobiście jest to znacznie lepsza odpowiedź. Mam bardzo małą wiedzę na temat Moq, ale wciąż zrozumiałem to od razu.
unrealsoul007
Do metod zwracających void użyłem .Callback ((ciąg a, wyjątek b, ciąg c) => wyrzuć nowy wyjątek (b. Komunikat));
tymtam,
62

Metoda ogólna Returns<T>ładnie poradzi sobie z tą sytuacją.

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

Lub jeśli metoda wymaga wielu danych wejściowych, określ je w następujący sposób:

_mock.Setup(x => x.DoSomething(It.IsAny<string>(), It.IsAny<int>())).Returns((string x, int y) => x);
WDuffy
źródło