Erste Schritte mit Mockito @Mock, @Spy, @Captor und @InjectMocks

Erste Schritte mit Mockito @Mock, @Spy, @Captor und @InjectMocks

1. Überblick

In diesem Tutorial werden dieannotations of the Mockito library -@Mock,@Spy,@Captor und@InjectMocks behandelt.

Für mehr Mockito-Gütehave a look at the series here.

Weitere Lektüre:

Mockito - Mit Spionen

Gute Nutzung von Spionen in Mockito und Unterschiede zwischen Spionen und Spott.

Read more

Mockito gegen EasyMock gegen JMockit

Eine schnelle und praktische Anleitung zum Verstehen und Vergleichen von Java-Spottbibliotheken.

Read more

Injizieren von Mockito Mocks in Frühlingsbohnen

Dieser Artikel zeigt, wie Sie mithilfe der Abhängigkeitsinjektion Mockito-Mocks in Spring Beans für Komponententests einfügen können.

Read more

2. Aktivieren Sie Mockito-Anmerkungen

Lassen Sie uns zunächst sehen, wie Sie die Verwendung von Anmerkungen mit Mockito-Tests aktivieren können.

Damit diese Anmerkungen aktiviert werden können, müssenannotate the JUnit test with a runner -MockitoJUnitRunner wie im folgenden Beispiel angegeben werden:

@RunWith(MockitoJUnitRunner.class)
public class MockitoAnnotationTest {
    ...
}

Alternativ können wir auchenable these annotations programmatically verwenden, indem wirMockitoAnnotations.initMocks() wie im folgenden Beispiel aufrufen:

@Before
public void init() {
    MockitoAnnotations.initMocks(this);
}

3. @Mock Anmerkung

Die am häufigsten verwendete Annotation in Mockito ist@Mock. Wir können@Mock verwenden, um verspottete Instanzen zu erstellen und einzufügen, ohneMockito.mock manuell aufrufen zu müssen.

Im folgenden Beispiel erstellen wir ein verspottetesArrayList auf manuelle Weise, ohne die Annotation von@Mockzu verwenden:

@Test
public void whenNotUseMockAnnotation_thenCorrect() {
    List mockList = Mockito.mock(ArrayList.class);

    mockList.add("one");
    Mockito.verify(mockList).add("one");
    assertEquals(0, mockList.size());

    Mockito.when(mockList.size()).thenReturn(100);
    assertEquals(100, mockList.size());
}

Und jetzt machen wir dasselbe, aber wir injizieren den Mock mit der Annotation@Mock:

@Mock
List mockedList;

@Test
public void whenUseMockAnnotation_thenMockIsInjected() {
    mockedList.add("one");
    Mockito.verify(mockedList).add("one");
    assertEquals(0, mockedList.size());

    Mockito.when(mockedList.size()).thenReturn(100);
    assertEquals(100, mockedList.size());
}

Beachten Sie, wie wir in beiden Beispielen mit dem Modell interagieren und einige dieser Interaktionen überprüfen, um sicherzustellen, dass sich das Modell korrekt verhält.

4. @Spy Anmerkung

Lassen Sie uns nun sehen, wie Sie die Annotation von@Spyverwenden, um eine vorhandene Instanz auszuspionieren.

Im folgenden Beispiel erstellen wir einen Spion vonList auf die alte Weise, ohne die Annotation von@Spyzu verwenden:

@Test
public void whenNotUseSpyAnnotation_thenCorrect() {
    List spyList = Mockito.spy(new ArrayList());

    spyList.add("one");
    spyList.add("two");

    Mockito.verify(spyList).add("one");
    Mockito.verify(spyList).add("two");

    assertEquals(2, spyList.size());

    Mockito.doReturn(100).when(spyList).size();
    assertEquals(100, spyList.size());
}

Machen wir jetzt dasselbe - spionieren Sie die Liste aus - aber verwenden Sie dazu die Annotation@Spy:

@Spy
List spiedList = new ArrayList();

@Test
public void whenUseSpyAnnotation_thenSpyIsInjectedCorrectly() {
    spiedList.add("one");
    spiedList.add("two");

    Mockito.verify(spiedList).add("one");
    Mockito.verify(spiedList).add("two");

    assertEquals(2, spiedList.size());

    Mockito.doReturn(100).when(spiedList).size();
    assertEquals(100, spiedList.size());
}

Beachten Sie, wie wir nach wie vor mit dem Spion interagieren, um sicherzustellen, dass er sich korrekt verhält. In diesem Beispiel haben wir:

  • Verwendete diereal-MethodespiedList.add(), um denspiedList Elemente hinzuzufügen.

  • Stubbed ist die MethodespiedList.size(), um100 anstelle von2 mitMockito.doReturn() zurückzugeben.

5. @Captor Anmerkung

Weiter - Lassen Sie uns sehen, wie Sie mit der Annotation@Captoreine Instanz vonArgumentCaptorerstellen.

Im folgenden Beispiel erstellen wirArgumentCaptor auf die alte Weise, ohne die Annotation@Captor zu verwenden:

@Test
public void whenNotUseCaptorAnnotation_thenCorrect() {
    List mockList = Mockito.mock(List.class);
    ArgumentCaptor arg = ArgumentCaptor.forClass(String.class);

    mockList.add("one");
    Mockito.verify(mockList).add(arg.capture());

    assertEquals("one", arg.getValue());
}

Lassen Sie uns nunmake use of @Captor für denselben Zweck verwenden - um eineArgumentCaptor-Instanz zu erstellen:

@Mock
List mockedList;

@Captor
ArgumentCaptor argCaptor;

@Test
public void whenUseCaptorAnnotation_thenTheSam() {
    mockedList.add("one");
    Mockito.verify(mockedList).add(argCaptor.capture());

    assertEquals("one", argCaptor.getValue());
}

Beachten Sie, wie der Test einfacher und lesbarer wird, wenn wir die Konfigurationslogik herausnehmen.

6. @InjectMocks Anmerkung

Lassen Sie uns nun diskutieren, wie die Annotation von@InjectMocksverwendet wird, um Scheinfelder automatisch in das getestete Objekt einzufügen.

Im folgenden Beispiel verwenden wir@InjectMocks, um das ScheinwordMap inMyDictionarydic zu injizieren:

@Mock
Map wordMap;

@InjectMocks
MyDictionary dic = new MyDictionary();

@Test
public void whenUseInjectMocksAnnotation_thenCorrect() {
    Mockito.when(wordMap.get("aWord")).thenReturn("aMeaning");

    assertEquals("aMeaning", dic.getMeaning("aWord"));
}

Und hier ist die KlasseMyDictionary:

public class MyDictionary {
    Map wordMap;

    public MyDictionary() {
        wordMap = new 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. Injizieren eines Spottes in einen Spion

Ähnlich wie beim obigen Test möchten wir vielleicht einem Spion einen Schein injizieren:

@Mock
Map wordMap;

@Spy
MyDictionary spyDic = new MyDictionary();

However, Mockito doesn’t support injecting mocks into spies, und die folgenden Testergebnisse in einer Ausnahme:

@Test
public void whenUseInjectMocksAnnotation_thenCorrect() {
    Mockito.when(wordMap.get("aWord")).thenReturn("aMeaning");

    assertEquals("aMeaning", spyDic.getMeaning("aWord"));
}

Wenn wir einen Mock mit einem Spion verwenden möchten, können wir den Mock manuell durch einen Konstruktor injizieren:

MyDictionary(Map wordMap) {
    this.wordMap = wordMap;
}

Anstatt die Annotation zu verwenden, können wir den Spion jetzt manuell erstellen:

@Mock
Map wordMap;

MyDictionary spyDic;

@Before
public void init() {
    MockitoAnnotations.initMocks(this);
    spyDic = Mockito.spy(new MyDictionary(wordMap));
}

Der Test wird nun bestanden.

8. Während der Verwendung von Annotation auf NPE stoßen __

Oft können wirrun into NullPointerException , wenn wir versuchen, die mit@Mockor@Spy annotierte Instanz tatsächlich zu verwenden, wie im Beispiel:

public class NPETest {

    @Mock
    List mockedList;

    @Test
    public void test() {
        Mockito.when(mockedList.size()).thenReturn(1);
    }
}

Meistens geschieht dies einfach, weil wir vergessen haben, Mockito-Annotationen ordnungsgemäß zu aktivieren.

Wir müssen uns also vor Augen halten, dass wir jedes Mal, wenn wir Mockito-Annotationen verwenden möchten, einen zusätzlichen Schritt unternehmen und sie initialisieren müssen, wie wir bereits zuvor erklärt haben.

9. Anmerkungen

Schließlich - hier sindsome notes über Mockito-Anmerkungen:

  • Verwenden Sie Annotation, um sich wiederholenden Mock-Erstellungscode zu minimieren

  • Verwenden Sie Anmerkungen, um den Test besser lesbar zu machen

  • Verwenden Sie@InjectMocks, um sowohl@Spy als auch@Mock Instanzen zu injizieren

10. Fazit

In diesem kurzen Tutorial haben wir die Grundlagen vonannotations in the Mockito library gezeigt.

Die Implementierung all dieser Beispiele kann inover on GitHub gefunden werden. Dies ist ein Maven-Projekt, daher sollte es einfach zu importieren und auszuführen sein.

Und natürlich für mehr Mockito-Gütehave a look at the series here.