Im Artikel Mockito: Unterschied doReturn ... when und when ... thenReturn hatten wir uns die Vorteile von when...thenReturn im Vergleich zu doReturn...when angeschaut. In diesem Artikel werden wir sehen, dass es für Mockito.spy() einen großen Unterschied macht, welche Variante wir wählen.
1 package de.webitect.mockito; 2 3 import org.junit.jupiter.api.Test; 4 import org.mockito.Mockito; 5 6 import static org.hamcrest.MatcherAssert.assertThat; 7 import static org.hamcrest.Matchers.is; 8 import static org.mockito.Mockito.*; 9 10 public class MockitoTest { 11 12 @Test 13 void testMocking(){ 14 //given 15 final String expectedName = "mockedName"; 16 final ClassToTest sut = mock(MockitoTest.ClassToTest.class); 17 when(sut.getName()).thenReturn(expectedName); // läuft! 18 doReturn(expectedName).when(sut).getName(); // läuft! 19 20 //when 21 final String name = sut.getName(); 22 23 //then 24 assertThat(name, is(expectedName)); 25 } 26 27 @Test 28 void testStubbing(){ 29 //given 30 final String expectedName = "stubbedName"; 31 final ClassToTest sut = spy(new ClassToTest()); 32 when(sut.getName()).thenReturn(expectedName); // NPE 33 doReturn(expectedName).when(sut).getName(); // läuft! 34 35 //when 36 final String name = sut.getName(); 37 38 //then 39 assertThat(name, is(expectedName)); 40 } 41 42 static class ClassToTest{ 43 private final MyObj myObj = null; 44 45 String getName(){ 46 return myObj.name; 47 } 48 } 49 50 static class MyObj{ 51 private final String name = "Hello World"; 52 } 53 } 54
Der Code ist einfach gehalten. Wir wollen die Methode getName() der Klasse ClassToTest testen.
Die Methode getName() gibt einen String zurück. Wir sehen leicht, dass das Ausführen zu einer NullPointerException
(NPE) führen wird, weil myObj final mit null initialisiert worden ist.
Unsere beiden Testmethoden nutzen einen Mock testMocking() und einen Spy testStubbing(). Im Fall des Mocks können wir beide Varianten
nutzen. Sowohl when...thenReturn als auch doReturn...when funktionieren. Nutzen wir einen Stub (spy(new ClassToTest())), wie in
unserer zweiten Testmethode, können wir when...thenReturn nicht nutzen, da dies bei der Testausführung zu einer NPE führt:
java.lang.NullPointerException at java.base/java.util.Objects.requireNonNull(Objects.java:208) at de.webitect.mockito.MockitoTest$ClassToTest.getName(MockitoTest.java:46) at de.webitect.mockito.MockitoTest.testStubbing(MockitoTest.java:32)
Wenn wir also Mockito.spy() nutzen, kann das Verwenden von when...thenReturn unerwartete Nebenwirkungen haben, da wir offensichtlich den Production Code durchlaufen und damit zum Beispiel in unserem Fall die NPE auslösen.