Jakie są różnice między mockami a stubami w Rhino Mocks?


149

Nie bawię się tym wystarczająco i zwykle używam mocków, ale zastanawiam się, jakie są różnice między tymi dwoma i kiedy użyć jednego lub drugiego w Rhino Mocks.

Aktualizacja:

Odpowiedź na swoje pytanie znalazłem również w słowach Ayende :

Różnica między skrótami a fałszywkami Dokładną

definicję tych terminów można znaleźć w tym artykule: Mocks to not stubs . Chcę się skupić na różnicy z punktu widzenia Rhino Mocks.

Makieta to obiekt, na który możemy postawić oczekiwania i który zweryfikuje, czy oczekiwane działania rzeczywiście miały miejsce. Odcinek to obiekt, którego używasz w celu przekazania do testowanego kodu. Możesz ustawić na nim oczekiwania, aby działał w określony sposób, ale te oczekiwania nigdy nie zostaną zweryfikowane. Właściwości kodu pośredniczącego będą automatycznie zachowywać się jak zwykłe właściwości i nie można ustawić dla nich oczekiwań.

Jeśli chcesz zweryfikować zachowanie testowanego kodu, użyjesz makiety z odpowiednim oczekiwaniem i zweryfikujesz to. Jeśli chcesz po prostu przekazać wartość, która może wymagać działania w określony sposób, ale nie jest przedmiotem tego testu, użyjesz kodu pośredniczącego.

WAŻNE: Niedźwiedź nigdy nie spowoduje niepowodzenia testu.


Odpowiedzi:


148

Jak na to

... Mówiąc prościej, istnieje różnica między obiektami Mock i Stub, a RhinoMocks uznaje to, co pozwala nam pisać testy, które lepiej określają ich przeznaczenie.

Mock obiekty służą do definiowania oczekiwań, tj .: W tym scenariuszu oczekuję wywołania metody A () z takimi a takimi parametrami. Mocks rejestrują i weryfikują takie oczekiwania.

Z drugiej strony kody kreskowe mają inny cel: nie rejestrują ani nie weryfikują oczekiwań, a raczej pozwalają nam „zastąpić” zachowanie, stan „fałszywego” obiektu w celu wykorzystania scenariusza testowego ...


Znalazłem inny przydatny post, który zawiera tę samą wiadomość, co zaakceptowana odpowiedź na to pytanie - martinfowler.com/articles/mocksArentStubs.html .
singh1469

20

Ogólnie rzecz biorąc, testy jednostkowe wywołują funkcje i metody, a następnie sprawdzają, czy miało miejsce oczekiwane zachowanie. Te funkcje i metody mogą wymagać parametrów. Aby spełnić te parametry, używamy kodów pośredniczących i makiet. Czasami możemy również mockować obiekty globalne.

Stubs

Stub to mały fałszywy obiekt, którego test może użyć jako parametru, aby wywołanie funkcji działało. Pozwala nam to zweryfikować zachowanie testowanej funkcji. Nie pozwala nam zweryfikować żadnych skutków ubocznych, ponieważ kod pośredniczący nie ma implementacji.

Mocks

Mock to kod pośredniczący z implementacją. Jeśli nasza testowana funkcja wchodzi w interakcję z naszym obiektem pozorowanym, możemy zweryfikować, czy z makietą wchodziliśmy zgodnie z oczekiwaniami.

Na przykład, powiedzmy, że mamy pozorowany obiekt użytkownika i chcemy sprawdzić, czy nasza metoda session.login zadziałała, możemy chcieć sprawdzić, czy ustawiono user.lastLoggedIn. Moglibyśmy stworzyć fałszywego użytkownika, który implementuje tę metodę. Kiedy wywołujemy session.login, możemy stwierdzić, że user.lastLoggedIn ma stan, jakiego oczekiwaliśmy.

Podsumowując

Mock to stub z implementacją, która pozwala nam testować efekty uboczne.

Czy ta różnica jest nadal ważna?

Podobnie jak różnica między porównaniami i metaforami, różnica między niedociągnięciami a kpiną jest subtelna i historyczna i być może ma więcej wspólnego z różnymi społecznościami i filozofiami w świecie testowania niż jakakolwiek większa różnica techniczna.

Reprezentują nieco inne podejście do testowania. Mock można zapisać jak stub. Fragment kodu można zwykle rozwinąć do postaci makiety.

Którego powinieneś użyć?

Może się okazać, że zaczynasz od tworzenia kodów pośredniczących, a później może się okazać, że będziesz musiał utworzyć pełne makiety dla niektórych obiektów. Możesz kpić sobie ze wszystkiego na bieżąco lub po prostu kpić w razie potrzeby.


7

Różnica między Mockiem a odgałęzieniem: za pomocą odgałęzienia poprawiasz dane wejściowe testu jednostkowego: więc twój test jednostkowy nie tworzy asercji na kodach pośredniczących i zastępczych, przepisując implementację jakiejś metody, naprawiając zachowanie fałszywego obiektu. za pomocą Mocka naprawiasz wynik testu jednostkowego: więc test jednostkowy stawia oczekiwanie na obiekcie Mocking, sprawdzając wewnętrzną interakcję w obiekcie pozorowanym.


Wydaje się, że mówisz, że twój test powinien "sprawdzać" wyjście z makiety. Jeśli to właśnie mówisz, nie masz racji. Mock nie powinien być testowany; jest tam, abyś mógł przetestować inny kod. A może twoje ostatnie zdanie oznacza coś innego?
Andrew Barber

1
Cześć Andrew, tak jak napisałem Z Mock'em naprawiasz wynik swojego testu, abyś go nie testował.W przeciwnym razie napisałem, że Mock pozwala ci sprawdzić interakcję (zachowanie w oczekiwaniu ... ;-)
Hassan Boutougha

1
OK, to ma więcej sensu. Dziękuję za wyjaśnienie!
Andrew Barber

> nie wykonuje asercji na stub. Dlaczego w wielu bibliotekach asercji wciąż istnieją metody aka should have been called withpotwierdzania stubparametrów.
hellboy,


0

Jedną z rzeczy, które zauważyłem, jest to, że kiedy używam MockRepository.GenerateMock, muszę jawnie ustawić oczekiwania dotyczące określonego wywołania metody, aby przechwycić to wywołanie. W przypadku stubów wydaje się, że automatycznie przechwytuje każdą metodę, o ile jest wirtualna.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.