Wyobraź sobie tę klasę
public class Foo {
private Handler _h;
public Foo(Handler h)
{
_h = h;
}
public void Bar(int i)
{
_h.AsyncHandle(CalcOn(i));
}
private SomeResponse CalcOn(int i)
{
...;
}
}
Mo (q) cking Handler w teście Foo, w jaki sposób mógłbym sprawdzić, co Bar()
przeszło _h.AsyncHandle
?
Odpowiedzi:
Możesz użyć metody Mock.Callback:
Jeśli chcesz sprawdzić tylko coś prostego w przekazanym argumencie, możesz to również zrobić bezpośrednio:
źródło
Callback<>()
metodzie Moq. Na przykład, jeśli metoda miałaby definicjęHandler.AnsyncHandle(string, SomeResponse)
, potrzebowałbyś/* ... */.Callback<string, SomeResponse>(r => result = r);
. Nie znalazłem tego wyraźnie w wielu miejscach, więc pomyślałem, że dodam to tutaj./* ... */.Callback<string, SomeResponse>((s1, s2) => { str1 = s1; result = s2});
.Callback((string s1, SomeResponse s2) => /* stuff */ )
Capture.In
pomocnika?Odpowiedź Gamlora zadziałała dla mnie, ale pomyślałem, że rozszerzę komentarz Johna Carpentera, ponieważ szukałem rozwiązania obejmującego więcej niż jeden parametr. Pomyślałem, że inni ludzie, którzy natkną się na tę stronę, mogą być w podobnej sytuacji. Znalazłem te informacje w dokumentacji Moq .
Posłużę się przykładem Gamlora, ale załóżmy, że metoda AsyncHandle przyjmuje dwa argumenty:
string
aiSomeResponse
obiekt.Zasadniczo wystarczy dodać inny
It.IsAny<>()
z odpowiednim typem, dodać inny typ doCallback
metody i odpowiednio zmienić wyrażenie lambda.źródło
Metoda Callback z pewnością zadziała, ale jeśli robisz to na metodzie z wieloma parametrami, może to być nieco rozwlekłe. Tutaj jest coś, czego użyłem do usunięcia części gotówki.
Oto źródło ArgumentCaptor:
źródło
Odpowiedź Gamlora działa, ale inny sposób (i który uważam za bardziej wyrazisty w teście) to ...
Weryfikacja jest bardzo potężna i warto poświęcić trochę czasu na przyzwyczajenie się.
źródło
Alternatywą jest również użycie
Capture.In
funkcjimoq
. Jest tomoq
funkcja OOTB, która umożliwia przechwytywanie argumentów w kolekcji.źródło
Callback
IMO. Ponieważ Capture jest używany bezpośrednio na liście parametrów, jest on znacznie mniej podatny na problemy podczas refaktoryzacji listy parametrów metody, a zatem sprawia, że testy są mniej kruche. W przypadku wywołania zwrotnego musisz utrzymywać parametry przekazane w konfiguracji zsynchronizowane z parametrami typu używanymi do wywołania zwrotnego i na pewno sprawiało mi to w przeszłości problemy.Możesz użyć
It.Is<TValue>()
dopasowania.źródło
Działa to również:
źródło
Wiele dobrych odpowiedzi tutaj! Idź z gotowym zestawem funkcji Moq, aż będziesz musiał dokonać asercji dotyczących kilku parametrów klas przekazanych do twoich zależności. Jeśli jednak znajdziesz się w takiej sytuacji, funkcja Moq Verify with It. Is matchers nie radzi sobie dobrze z izolowaniem błędu testu, a sposób Returns / Callback przechwytywania argumentów dodaje niepotrzebne wiersze kodu do twojego testu (i długie testy są dla mnie nie do przyjęcia).
Oto sedno: https://gist.github.com/Jacob-McKay/8b8d41ebb9565f5fca23654fd944ac6b z rozszerzeniem Moq (4.12), które napisałem, które daje bardziej deklaratywny sposób tworzenia twierdzeń o argumentach przekazywanych do kpiny, bez wspomnianych powyżej wad. Oto, jak teraz wygląda sekcja Weryfikuj:
Byłbym podekscytowany, gdyby Moq dostarczył funkcję, która osiągnęła to samo, będąc deklaratywną i zapewniając izolację awarii. Skrzyżowane palce!
źródło