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, we can specify what should be returned when a method is called. This makes unit testing easier as we don't need to modify existing classes. Mockito supports two ways of doing this: when-thenReturn and doReturn-when. In most cases, when-thenReturn is used and has better readability.

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

However, sometimes we need to consider using doReturn-when because of different behaviors.

Type safety

The doReturn parameter, unlike thenReturn, is an Object. Therefore, there is no type checking at compile time. When the types do not match at runtime, it throws a WrongTypeOfReturnValue exception.

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

This is the main reason why when-thenReturn is a better option if possible.

Side effects

Despite the lack of type safety, the advantage of doReturn-when is that it has no side effects. In Mockito, there is a side effect on the actual method call. To understand this, we need to know when a real method call occurs.

Generally, we need to create a mock object with Mockito.mock before specifying a return value. When we call a method of the mock object, it returns the specified value but does not perform anything defined in the class. It has no side effects, so when-thenReturn and doReturn-when behave almost identically, except that one has type safety.

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

The difference arises when you create a spy with Mockito.spy. A spy object is bound to a real object. Therefore, when you call a method, there is a real method call. This is true even when we use when-thenReturn. This is because of the when parameter, which includes a way of calling a method. For example: user.getName(). In contrast, when you use doReturn-when, the when parameter is only passed the user object.

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

A side effect does not always occur, but common scenarios include:

A method throws an exception due to a precondition check. Birim testi yaparken bir yöntem istemediğinizi yapar. Örneğin, ağ veya disk erişimi. For example, List#get() throws an exception if the list is smaller. doReturn can specify a value without throwing an exception.

List list = new LinkedList();
List spy = spy(list);

// Problem: gerçek yöntem spy.get(0) olarak adlandırılır ve IndexOutOfBoundsException'ı atar (liste henüz boş)
when(spy.get(0)).thenReturn("foo");

// Stubbing için doReturn() kullanmalıyız
doReturn("foo").when(spy).get(0);

Another example is modifying a class behavior for unit testing. AccountService is the target under test, so it cannot be mocked. With Mockito.spy and doReturn(), you can perform unit testing without network access.

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();
    }
}

If there are no side effects, we can use when-thenReturn for the spy object.

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

when(...) thenReturn(...) makes a real method call right before returning the specified value. So if the called method throws an exception, we have to deal with it.

doReturn(...) when(...) does not make a method call.

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

// metodu çağırmadığı için çalışır
doReturn("test").when(testClass).testEdilecekMetod();

// metod'u çağırdığı için NullPointerException fırlatır
when(testClass.testEdilecekMetod()).thenReturn("test");

Conclusion

We can use doReturn-when to specify a return value without causing a side effect on a spied object. It is useful, but should be used rarely. The more you use better patterns like MVP, MVVM, and dependency injection, the less chance you will have to use Mockito.spy. Then, you can use Mockito.mock, which is safer and more readable.

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