Stubbing von Spies und Behandlung von Ausnahmen
In diesem Schritt werden wir lernen, wie man einen Spy stubbt, um sein Standardverhalten zu überschreiben, und verstehen, wie man Ausnahmen behandelt, die beim Verwenden von Mockito auftreten können.
Stubbing eines Spies
Spies verwenden standardmäßig die echten Methoden eines Objekts, aber manchmal möchten wir dieses Verhalten aus Testzwecken ändern. Dies wird "Stubbing" des Spies genannt. Fügen wir eine Testmethode hinzu, die zeigt, wie man einen Spy stubbt:
@Test
public void testStubbingSpy() {
// Create a spy of ArrayList
ArrayList<Integer> spyList = Mockito.spy(new ArrayList<>());
// Add an element
spyList.add(5);
// Verify the element was added
Mockito.verify(spyList).add(5);
// By default, contains() should return true for element 5
assertTrue(spyList.contains(5));
System.out.println("Stubbing Example - Default behavior: spyList.contains(5) = " + spyList.contains(5));
// Stub the contains() method to always return false for the value 5
Mockito.doReturn(false).when(spyList).contains(5);
// Now contains() should return false, even though the element is in the list
assertFalse(spyList.contains(5));
System.out.println("Stubbing Example - After stubbing: spyList.contains(5) = " + spyList.contains(5));
// The element is still in the list (stubbing didn't change the list content)
assertEquals(1, spyList.size());
assertEquals(Integer.valueOf(5), spyList.get(0));
System.out.println("Stubbing Example - Spy List Content: " + spyList);
}
Wichtige Anmerkung zum Stubbing
Beim Stubbing von Spy-Methoden wird empfohlen, doReturn()
, doThrow()
, doAnswer()
usw. anstelle von when()
zu verwenden. Dies liegt daran, dass bei Spies die Syntax when().thenReturn()
möglicherweise die echte Methode während des Stubbing aufruft, was unerwartete Nebeneffekte verursachen kann.
Beispiel:
// This might call the real get() method, causing issues if index 10 doesn't exist
Mockito.when(spyList.get(10)).thenReturn(99); // May throw IndexOutOfBoundsException
// This is the correct way to stub a spy
Mockito.doReturn(99).when(spyList).get(10); // Safe, doesn't call the real method
Behandlung der NotAMockException
Wenn Sie versuchen, Mockitos Überprüfungsmethoden auf ein normales Objekt (kein Mock oder Spy) anzuwenden, erhalten Sie eine NotAMockException
. Fügen wir eine Testmethode hinzu, um diese Ausnahme zu demonstrieren:
@Test
public void testNotAMockException() {
try {
// Create a regular ArrayList (not a mock or spy)
ArrayList<Integer> regularList = new ArrayList<>();
regularList.add(5);
// Try to verify an interaction on a regular object
Mockito.verify(regularList).add(5);
fail("Expected NotAMockException was not thrown");
} catch (NotAMockException e) {
// Expected exception
System.out.println("NotAMockException Example - Caught expected exception: " + e.getMessage());
assertTrue(e.getMessage().contains("Argument passed to verify() is not a mock"));
}
}
Lassen Sie uns unseren aktualisierten Code kompilieren:
cd ~/project
javac -cp lib/junit.jar:lib/mockito-core.jar:lib/byte-buddy.jar:lib/byte-buddy-agent.jar:lib/objenesis.jar:lib/hamcrest-core.jar MockitoSpyDemo.java
Der Code sollte ohne Fehler kompilieren. In diesem Schritt haben wir gelernt, wie man Spy-Methoden stubbt, um ihr Standardverhalten zu überschreiben, und wie man die NotAMockException
behandelt, die auftritt, wenn man Überprüfungsmethoden auf normale Objekte anwendet.
Im nächsten Schritt werden wir Mocks und Spies vergleichen, um ihre wesentlichen Unterschiede zu verstehen.