Kom godt i gang med Mockito @Mock, @Spy, @Captor og @InjectMocks
1. Oversigt
I denne vejledning dækker vi annoteringer af Mockito-biblioteket – @Mock, @Spion, @Captorog @InjectMocks.
For mere Mockito godhed, se på serien her.
2. Aktivér Mockito-kommentarer
Før vi går videre, lad os undersøge forskellige måder at muliggøre brugen af kommentarer med Mockito-tests.
2.1. MockitoJUnitRunner
Den første mulighed, vi har, er at kommentere JUnit-testen med en MockitoJUnitRunner som i følgende eksempel:
@RunWith (MockitoJUnitRunner.class) offentlig klasse MockitoAnnotationTest {...}
2.2. MockitoAnnotations.initMocks ()
Alternativt kan vi aktivere Mockito-annoteringer programmatisk også ved at påberåbe sig MockitoAnnotations.initMocks ():
@Før offentlig ugyldig init () {MockitoAnnotations.initMocks (dette); }
2.3. MockitoJUnit.rule ()
Endelig vi kan bruge en MockitoJUnit.rule ()som vist nedenfor:
offentlig klasse MockitoInitWithMockitoJUnitRuleUnitTest {@Rule public MockitoRule initRule = MockitoJUnit.rule (); ...}
I dette tilfælde skal vi huske at gøre vores regel offentlig.
3. @Mock Kommentar
Den mest anvendte annotering i Mockito er @Mock. Vi kan bruge @Mock at oprette og injicere spottede forekomster uden at skulle ringe Mockito.mock manuelt.
I det følgende eksempel opretter vi en mocked ArrayList med den manuelle måde uden brug @Mock kommentar:
@Test offentlig ugyldig nårNotUseMockAnnotation_thenCorrect () {List mockList = Mockito.mock (ArrayList.class); mockList.add ("en"); Mockito.verify (mockList) .add ("en"); assertEquals (0, mockList.size ()); Mockito.when (mockList.size ()). Derefter Retur (100); assertEquals (100, mockList.size ()); }
Og nu gør vi det samme, men vi injicerer mock ved hjælp af @Mock kommentar:
@Mock List mockedList; @Test offentlig ugyldigt nårUseMockAnnotation_thenMockIsInjected () {mockedList.add ("one"); Mockito.verify (mockedList) .add ("one"); assertEquals (0, mockedList.size ()); Mockito.when (mockedList.size ()). Derefter Retur (100); assertEquals (100, mockedList.size ()); }
Bemærk hvordan - i begge eksempler interagerer vi med mocken og verificerer nogle af disse interaktioner - bare for at sikre, at mocken opfører sig korrekt.
4. @Spion Kommentar
Lad os nu se, hvordan du bruger @Spion kommentar for at spionere på en eksisterende forekomst.
I det følgende eksempel opretter vi en spion af en Liste med den gamle måde uden brug @Spion kommentar:
@Test offentlig ugyldig nårNotUseSpyAnnotation_thenCorrect () {List spyList = Mockito.spy (new ArrayList ()); spyList.add ("en"); spyList.add ("to"); Mockito.verify (spyList) .add ("one"); Mockito.verify (spyList) .add ("to"); assertEquals (2, spyList.size ()); Mockito.doReturn (100). Når (spyList) .størrelse (); assertEquals (100, spyList.size ()); }
Lad os nu gøre det samme - spionér på listen - men gør det ved hjælp af @Spion kommentar:
@Spy-liste spiedList = ny ArrayList (); @Test offentlig ugyldigt nårUseSpyAnnotation_thenSpyIsInjectedCorrectly () {spiedList.add ("one"); spiedList.add ("to"); Mockito.verify (spiedList) .add ("en"); Mockito.verify (spiedList) .add ("to"); assertEquals (2, spiedList.size ()); Mockito.doReturn (100). Når (spiedList) .størrelse (); assertEquals (100, spiedList.size ()); }
Bemærk hvordan du som før interagerer med spionen her for at sikre, at den opfører sig korrekt. I dette eksempel:
- Brugt ægte metode spiedList.add () for at tilføje elementer til spiedList.
- Stubbed metoden spiedList.size () at vende tilbage 100 i stedet for 2 ved brug af Mockito.doReturn ().
5. @Captor Kommentar
Næste - lad os se, hvordan du bruger @Captor kommentar for at oprette en ArgumentCaptor eksempel.
I det følgende eksempel - opretter vi en ArgumentCaptor med den gamle måde uden brug @Captor kommentar:
@Test offentlig ugyldig nårNotUseCaptorAnnotation_thenCorrect () {List mockList = Mockito.mock (List.class); ArgumentCaptor arg = ArgumentCaptor.forClass (String.class); mockList.add ("en"); Mockito.verify (mockList) .add (arg.capture ()); assertEquals ("en", arg.getValue ()); }
Lad os nu gøre brug af @Captormed det samme formål - at skabe en ArgumentCaptor eksempel:
@Mock List mockedList; @Captor ArgumentCaptor argCaptor; @Test offentlig ugyldig nårUseCaptorAnnotation_thenTheSam () {mockedList.add ("one"); Mockito.verify (mockedList) .add (argCaptor.capture ()); assertEquals ("en", argCaptor.getValue ()); }
Bemærk, hvordan testen bliver enklere og mere læselig, når vi tager konfigurationslogikken ud.
6. @InjectMocks Kommentar
Lad os nu diskutere, hvordan man bruger @InjectMocks kommentar - for automatisk at indsprøjte mock-felter i det testede objekt.
I det følgende eksempel bruger vi @InjectMocks at injicere mock wordMap ind i MyDictionarydic:
@Mock Map wordMap; @InjectMocks MyDictionary dic = ny MyDictionary (); @Test offentligt ugyldigt nårUseInjectMocksAnnotation_thenCorrect () {Mockito.when (wordMap.get ("aWord")). DerefterReturn ("aMeaning"); assertEquals ("aMeaning", dic.getMeaning ("aWord")); }
Og her er klassen MyDictionary:
offentlig klasse MyDictionary {Map wordMap; offentlig MyDictionary () {wordMap = ny HashMap (); } public void add (final String word, final String meaning) {wordMap.put (word, meaning); } public String getMeaning (final String word) {return wordMap.get (word); }}
7. Injektion af en mock i en spion
I lighed med ovenstående test vil vi måske injicere en mock i en spion:
@Mock Map wordMap; @Spy MyDictionary spyDic = ny MyDictionary ();
Imidlertid understøtter Mockito ikke indsprøjtning af mocks i spioner, og følgende testresultater med en undtagelse:
@Test offentligt ugyldigt nårUseInjectMocksAnnotation_thenCorrect () {Mockito.when (wordMap.get ("aWord")). DerefterReturn ("aMeaning"); assertEquals ("aMeaning", spyDic.getMeaning ("aWord")); }
Hvis vi vil bruge en mock med en spion, kan vi manuelt injicere mocken gennem en konstruktør:
MyDictionary (Map wordMap) {this.wordMap = wordMap; }
I stedet for at bruge kommentaren kan vi nu oprette spionen manuelt:
@Mock Map wordMap; MyDictionary spyDic; @Før offentlig ugyldig init () {MockitoAnnotations.initMocks (dette); spyDic = Mockito.spy (ny MyDictionary (wordMap)); }
Testen vil nu bestå.
8. Kører ind i NPE, mens du bruger kommentar
Ofte kan vi løbe ind i NullPointerException når vi forsøger at bruge den instans, der er kommenteret med @Mock eller @Spion:
offentlig klasse MockitoAnnotationsUninitializedUnitTest {@Mock List mockedList; @Test (forventet = NullPointerException.class) offentlig ugyldigt nårMockitoAnnotationsUninitialized_thenNPEThrown () {Mockito.when (mockedList.size ()). ThenReturn (1); }}
For det meste sker dette simpelthen fordi vi glemte at aktivere Mockito-kommentarer korrekt.
Så vi skal huske på, at hver gang vi vil bruge Mockito-kommentarer, skal vi tage et ekstra trin og initialisere dem som vi allerede har forklaret tidligere.
9. Bemærkninger
Endelig - her er nogle noter om Mockito-kommentarer:
- Mockitos annoteringer minimerer gentagne koder til oprettelse af mock
- De gør test mere læsbare
- @InjectMocks er nødvendig til injektion af begge dele @Spion og @Mock tilfælde
10. Konklusion
I denne hurtige vejledning viste vi det grundlæggende i bemærkninger i Mockito-biblioteket.
Implementeringen af alle disse eksempler kan findes på GitHub. Dette er et Maven-projekt, så det skal være let at importere og køre som det er.
Og selvfølgelig, for mere Mockito godhed, se på serien her.