Anıl Şenocak Anıl Şenocak
Yazılım Mühendisi
Cover image
2026-07-11 0 toplam yorum
Mockito: doReturn vs. thenReturn

In Mockito können wir festlegen, was zurückgegeben werden soll, wenn eine Methode aufgerufen wird. Dies erleichtert Unit-Tests, da wir die bestehenden Klassen nicht ändern müssen. Mockito unterstützt zwei Möglichkeiten, dies zu tun: when-thenReturn und doReturn-when. In den meisten Fällen wird when-thenReturn verwendet, da es eine bessere Lesbarkeit bietet.

User user = Mockito.mock(User.class);
when(user.getName()).thenReturn("John");

Manchmal müssen wir jedoch die Verwendung von doReturn-when in Betracht ziehen, da es ein anderes Verhalten aufweist.

Typsicherheit

Der Parameter von doReturn ist im Gegensatz zu thenReturn ein Object. Daher gibt es zur Kompilierzeit keine Typprüfung. Wenn der Typ zur Laufzeit nicht übereinstimmt, wird eine WrongTypeOfReturnValue-Exception ausgelöst.

doReturn(true).when(user).getName());

Dies ist der Hauptgrund, warum when-thenReturn nach Möglichkeit die bessere Wahl ist.

Nebenwirkungen

Trotz der fehlenden Typsicherheit liegt der Vorteil von doReturn-when darin, dass es keine Nebenwirkungen hat. In Mockito kann ein realer Methodenaufruf Nebenwirkungen haben. Um dies zu verstehen, müssen wir wissen, wann ein echter Methodenaufruf stattfindet.

Normalerweise müssen wir ein Mock-Objekt mit Mockito.mock erstellen, bevor wir einen Rückgabewert festlegen. Wenn wir eine Methode des Mock-Objekts aufrufen, gibt sie einen bestimmten Wert zurück, führt aber nichts aus, was in der Klasse definiert ist. Es gibt keine Nebenwirkungen, sodass sich when-thenReturn und doReturn-when fast identisch verhalten, abgesehen von der Typsicherheit.

User user = Mockito.mock(User.class);
when(user.getName()).thenReturn("Lorem");
doReturn(true).when(user).getName());

Der Unterschied zeigt sich, wenn Sie einen Spy mit Mockito.spy erstellen. Ein Spy-Objekt ist an ein reales Objekt gebunden. Daher erfolgt beim Aufruf einer Methode ein echter Methodenaufruf. Dies gilt auch dann, wenn wir when-thenReturn verwenden. Der Grund dafür ist der when-Parameter, der einen Weg zum Aufrufen einer Methode enthält. Zum Beispiel: user.getName(). Im Gegensatz dazu ist bei der Verwendung von doReturn-when der Parameter von when nur das user-Objekt selbst.

User user = Mockito.spy(new User());

Eine Nebenwirkung tritt nicht immer auf, aber typische Fälle sind:

  • Eine Methode wirft eine Exception bei einer Vorbedingungsprüfung.
  • Eine Methode führt beim Unit-Testing unerwünschte Aktionen aus. Zum Beispiel Netzwerk- oder Festplattenzugriff.
  • Beispielsweise wirft List#get() eine Exception, wenn die Liste zu klein ist. Mit doReturn kann ein Wert ohne Exception festgelegt werden.
List list = new LinkedList();
List spy = spy(list);

// Problem: Die echte Methode spy.get(0) wird aufgerufen und wirft eine IndexOutOfBoundsException (da die Liste noch leer ist)
when(spy.get(0)).thenReturn("foo");

// Wir müssen doReturn() für das Stubbing verwenden
doReturn("foo").when(spy).get(0);

Ein weiteres Beispiel ist das Ändern des Verhaltens einer Klasse für Unit-Tests. AccountService ist das zu testende Ziel (Target under Test) und kann daher nicht gemockt werden. Mit Mockito.spy und doReturn() können Sie Unit-Tests ohne Netzwerkzugriff durchführen.

public class AccountService extends IntentService {
    @Override
    protected void onHandleIntent(Intent intent) {
        if("DELETE".equals(intent.getAction())) {
            sendDeleteRequest();
        }
    }
    protected void sendDeleteRequest() {
        // Network access
    }
}
@RunWith(RobolectricTestRunner.class)
public class AccountServiceTest {

    @Test
    public void shouldSendDeleteRequest_whenDeleteAction() {
        AccountService accountService = spy(new AccountService("Account"));
        doNothing().when(accountService).sendDeleteRequest();

        accountService.onHandleIntent(new Intent("DELETE"));

        verify(accountService).sendDeleteRequest();
    }
}

Wenn keine Nebenwirkungen vorliegen, können wir when-thenReturn für das Spy-Objekt verwenden.

User user = Mockito.spy(new User());
when(user.getName()).thenReturn("John");

when(...) thenReturn(...) führt einen echten Methodenaufruf durch, kurz bevor der angegebene Wert zurückgegeben wird. Wenn die aufgerufene Methode also eine Exception wirft, müssen wir uns darum kümmern.

doReturn(...) when(...) führt keinen Methodenaufruf durch.

public class TestClass {
     protected String testEdilecekMetod() {
          throw new NullPointerException();
     } 
}
@Spy
TestClass testClass;

// Funktioniert, da die Methode nicht aufgerufen wird
doReturn("test").when(testClass).testEdilecekMetod();

// Wirft NullPointerException, da die Methode aufgerufen wird
when(testClass.testEdilecekMetod()).thenReturn("test");

Fazit

Wir können doReturn-when verwenden, um einen Rückgabewert festzulegen, ohne eine Nebenwirkung auf einem Spy-Objekt zu erzeugen. Es ist nützlich, sollte aber selten verwendet werden. Je mehr Sie bewährte Entwurfsmuster wie MVP, MVVM und Dependency Injection nutzen, desto seltener müssen Sie Mockito.spy verwenden. Stattdessen können Sie das sicherere und lesbarere Mockito.mock verwenden.

Yorumlar
Henüz yorum yok. İlk yorumu sen yaz.
Yorum Bırak
Adınız (isteğe bağlı)
Yorumunuzu yazın...
0/500