2016-07-25 8 views
12

W projekcie nad którym pracuję teraz, często widzę @Spy i @InjectMocks używane razem na polu. Ale nigdy nie widziałem tego w żadnych tutorialach lub innych zasobach. Wyszukałem tę samą kombinację, ale nie znalazłem nic innego poza tym wątkiem na GitHub: https://github.com/mockito/mockito/issues/169Czy odradza się używanie @Spy i @InjectMocks w tym samym polu?

Co sprawia, że ​​myślę, że używamy go w dziwny sposób.

Uwaga: Powodem, dla którego uważam, że używanie obu adnotacji jednocześnie ma sens, jest to, że jeśli użyjesz tylko @InjectMocks, Mockito spróbuje utworzyć instancję klasy za pomocą konstruktora no-args. Ale jeśli nie masz żadnego contruktora no-args i dodajesz @Spy możesz użyć obiektu bez konieczności pustego konstruktora.

Edycja: Kolejnym ważnym zastosowaniem jest to, że można stosować tylko metody pośrednie, jeśli używa się obu adnotacji.

Odpowiedz

12

Jest rzadkością i prawdopodobnie niewłaściwym używanie razem @Spy i @InjectMocks.

@InjectMocks działa jako swego rodzaju iniekcji zależnościach dla testowanego systemu: Jeśli masz test, który definiuje @Mock lub @Spy prawego typu Mockito będzie inicjować żadnych pól instancji @InjectMocks z te pola. Może to być przydatne, jeśli w inny sposób nie ustrukturyzowałeś testowania systemu pod kątem zastrzyku zależności (lub jeśli korzystasz z frameworka DI, które wykonuje iniekcje polowe) i chcesz zastąpić te zależności mockami. Może być dość kruchy - niedopasowane pola będą milcząco ignorowane i pozostaną niezmienione, jeśli nie zostaną ustawione w inicjatorze, ale pozostaną przyzwoitą adnotacją dla twojego testowanego systemu.

@Spy, podobnie jak @Mock, służy do konfigurowania testów podwójnych pod numerem; powinieneś go używać, gdy masz współpracownika, który chcesz pobrać lub zweryfikować. Zauważ, że @Spy i @Mock zawsze mają na celu dla zależności, a nie dla twojego testowanego systemu.

Idealnie nie powinieneś mieć żadnej klasy, która spełnia obie role w tym samym teście, albo możesz napisać test, który skrupulatnie testuje zachowane zachowanie, a nie rzeczywiste zachowanie produkcyjne. W każdym razie trudniej będzie dokładnie określić, co pokrywa test, a co za tym, co zachowałeś.

Oczywiście może to nie mieć zastosowania, jeśli próbujesz użyć Mockito, aby przetestować pojedynczą metodę w izolacji, a chcesz wywołać funkcję kodu do jednej metody podczas testowania drugiej. Może to jednak wskazywać na to, że twoja klasa narusza zasadę odpowiedzialności pojedynczej, i że powinieneś podzielić klasę na wiele niezależnych klas, które współpracują ze sobą. Następnie w teście możesz zezwolić instancjom na pełnienie dokładnie jednej roli i nigdy nie będziesz potrzebować obu adnotacji naraz.

+0

Czy to koreluje z funkcją MockitoAnnotations.initMocks()? –

+1

@Igor Co masz na myśli przez "korelować"? Wywołanie funkcji 'initMocks' nie powoduje wyjątku, ale Mockito nie robi wszystkiego, co może być potrzebne w przypadku obu adnotacji. Oprócz przyczyn filozoficznych, o których pisałem powyżej, zobacz także [numer # 489 na Google Code] (https://code.google.com/archive/p/mockito/issues/489), by poznać ograniczenia implementacji. –

+0

@JeffBowman Nie jest rzadkością, że publiczna metoda A wywołuje publiczną metodę B tej samej klasy. Dlaczego miałby to być zły projekt? Testowałem już metodęB indywidualnie i chcę przetestować metodęA przez stubb subBall. Czy jest lepszy sposób niż posiadanie obu adnotacji na tej samej klasie? Czy możliwe jest wsteczne odniesienie do siebie? – acheron55

Powiązane problemy