Jaki jest cel Verifiable () w Moq?

125

Jaki jest cel Verifiable()?

Jeśli zweryfikuję a Mocki pominę to, nadal sprawdza SetUp.

Edycja: W ten VerifyAll()sposób użyłem powodu, dla którego wszystko zostało zweryfikowane. Po zmianie na Verify()tylko moje .Verifiable() SetUpbyły sprawdzane.

Castrohenge
źródło

Odpowiedzi:

83

DODATEK: Jak stwierdza druga odpowiedź, celem .Verifiablejest włączenie Setupdo zestawu „odroczonych Verify(...)połączeń”, które można następnie uruchomić za pomocąmock.Verify() .

Wyjaśnienie OP jasno określa, że ​​taki był cel, a jedynym problemem było ustalenie, dlaczego to nie działa, ale jak sugerował @Liam, odpowiedź powinna naprawdę dotyczyć również tego: - Kluczowe przypadki użycia, o ile mogę zobacz:

  • utrzymanie SUCHOŚCI między a mock.Setup()amock.Verify
  • pozwalając na odłączenie konfiguracji weryfikacji od samego Verifypołączenia (np. można ustawić ją w innej metodzie pomocniczej)

... i wracając do mojej odpowiedzi, która zwięźle mówi: „bądź ostrożny, ponieważ powyższe zalety są powszechnie uważane za przeważone przez wpływ, jaki osiągnięcie tych celów ma na czytelność i łatwość konserwacji testów, które zbytnio opierają się na takich konstrukcjach”

ORYGINAŁ: Zauważ, że jeśli to możliwe, należy zamiast tego postępować zgodnie z układem AAA, a zatem powinno się wykonywać jawne mock.Verify( expression )wywołania po zakończeniu pracy, a nie mock.Setup( ... ).Verifiable()sparować z a mock.Verify()lubmock.VerifyAll() gdziekolwiek jest to możliwe ( źródło : @kzu ).

Ruben Bartelink
źródło
7
@EricSmith Patrząc wstecz, myślę, że nie powiedziałem tego wystarczająco mocno. Dzielenie pracy na łączenie AAA przynosi znacznie większe korzyści niż nadmierna koncentracja na podobieństwach między fazą aranżacji i potwierdzenia. W 90% przypadków można coś zyskać z niuansów sposobu, w jaki na końcu wyrażasz wywołania Verify, więc powinieneś poświęcić dużo czasu na optymalizację pod tym kątem, nawet jeśli w niektórych przypadkach wydaje się to bolesne powielanie. Jednym z punktów manning.com/osherove bardzo dobrze jest to, że sprawienie, by test miał sens dla kogoś, kto wskoczył, jest krytyczny - więc trzymaj się konwencji!
Ruben Bartelink,
3
Zwykle nie jestem osobą, która idzie pod prąd akceptowanej mądrości, ale nie jestem jeszcze przekonany co do zalet AAA w porównaniu z Verifyable()/ VerifyAll()we wszystkich przypadkach. Mój obecny test jednostkowy ma dużą liczbę Setup(...)połączeń (> 30). Może dopasować każdy z równoważną Verify (), aby spełnić konwencję, ale powoduje to dużą liczbę duplikatów kodu i będzie trudniejsze do utrzymania i odczytania w miarę wzrostu liczby testów jednostkowych. Myślę, że naprawdę pytam, czy można zrobić wyjątki, jeśli jest duża liczba konfiguracji, czy też unika Verifiable()się sztywnej i szybkiej reguły?
Steve Chambers
5
@SteveChambers Kluczowym elementem AAA jest to, że nie jest to A * - powinien istnieć jeden akt i jedno potwierdzenie. Więc chociaż masz techniczną poprawność, mówiąc, że jest to dla ciebie mniej kodu, zbieg okoliczności, które z twoich ustawień mają zastosowanie do których (pod) aktów i (pod) ataków, niezmiennie staną się polem minowym. Więc nie, to nie jest trudne i szybkie, ale powiedziałbym, że sugerowanie, że jest nawet blisko 50:50, byłoby bardzo złą radą. (Zwróć też uwagę, że nie musisz wykonywać konfiguracji, aby przeprowadzić weryfikację, chyba że próbujesz wprowadzić określone zachowanie podczas aktu - co jest kolejnym elementem jasnych testów)
Ruben Bartelink
1
@Liam I rzeczywiście, jest całkowicie w porządku, że nadal jesteś przekonany, że to odpowiednie narzędzie do Twojej pracy - tak naprawdę chodzi mi o to, że jest źle postrzegany jako ogólne podejście do pisania testów z próbami - tj. Pomimo tego, że zgrabnie osiąga SUCHOŚĆ między a Setupa a Verify, której może brakować, można uzyskać wyższą wygraną, którą można osiągnąć jedynie poprzez złagodzenie ograniczenia DRY w sposób sugerowany przez AAA i rodzinę strategii, które zdecydowanie implikują
Ruben Bartelink
1
@Liam Dzięki za szturchnięcie; Zaktualizowałem moją odpowiedź, ponieważ masz rację w swoim punkcie. W czasach, gdy odpowiadałem na TAK pytania, takie jak to, moim zdaniem ogólnie było zwięźle podać atomową odpowiedź, a następnie pozwolić konkurencyjnym odpowiedziom, takim jak druga, wypełnić mapę. W dzisiejszych czasach (jeśli nadal miałbym czas, aby odpowiedzieć na pytania), prawdopodobnie spróbuję udzielić pełniejszej odpowiedzi, która stała się w pierwszej kolejności.
Ruben Bartelink
54

Gdy Verify()metoda jest wywoływana na końcu testu, a którekolwiek z oczekiwań oznaczonych jako weryfikowalne nie zostało wywołane, wówczas występuje wyjątek thrown.

VerifyAll() nie sprawdza weryfikowalnych oczekiwań.

Suvesh Pratapa
źródło
czy mógłbyś wyjaśnić trochę więcej o tym, że VerifyAll () nie sprawdza weryfikowalnych oczekiwań?
JW
@JW Oznacza to, że VerifyAll weryfikuje wszystkie konfiguracje bez rozważania, czy zostały one oznaczone jako weryfikowalne oczekiwania.
phoog