When-then vs do when mockito – Java Code Geeks


Writing unit tests is very important for better software quality. For unit tests Mockito is one of the most common choices for developers. Mockito offers different ways to mock methods, like do… when and when… then. Most of the time, we are faced with the question of using when-then vs. doing-when. We will see all the differences in detail.

In Mockito, we can make fun of the methods in 2 different ways,

DatabaseService service = Mockito.mock(DatabaseService.class);
when(service.isConnected()).thenReturn(true);
doReturn(true).when(service.isConnected())

Different methods to do when

  • do not do anything()
  • doReturn (Object toReturn)
  • doReturn (Object toBeReturned, Object… toBeReturnedNext)
  • doAnswer (Reply to answer)
  • doCallRealMethod ()
  • doThrow (Throwa = the … ToBeThrown)
  • doThrow (Class toBeThrown)
  • doThrow (Class toBeThrown, Class… toBeThrownNext)

Different methods for when-then

  • thenReturn (T var1)
  • thenReturn (T var1, T… var2)
  • thenAnswer (Response var1)
  • then (Response var1)
  • thenCallRealMethod ()
  • thenThrow (Throwable… var1)
  • thenThrow (Class var1)
  • thenThrow (Class var1, Class… var2)

Recommended difference between thenReturn and thenAnswer in mockito

In most cases when-then is used because it offers greater readability, but there are some cases where the two approaches behave differently and should be used with caution.

  1. Validation of the type of mocking return
  2. Mocking methods of spy objects
  3. Mocking void methods

Validation of the return type for the simulated object

The return type of doReturn (..) is Object while the return type of thenReturn (..) conforms to the method type. So in case of doReturn, we might get org.mockito.exceptions.misusing.WrongTypeOfReturnValue if an incompatible return value is used. In the case of thenReturn, if we use an incorrect value, the application will not be compiled.

List<String> mockedList = Mockito.mock(ArrayList.class);
Mockito.when(mockedList.size()).thenReturn("test");

This will give a compilation error, so easy to fix.

List<String> mockedList = Mockito.mock(ArrayList.class);
doReturn("Test").when(mockedList).size();

This will compile but fail to run.

For simulated objects, it is better to use the when-then option because it provides return type checking and is more readable. However, it has drawbacks in the case of spied objects and empty methods.

Mocking Methods of the Spy Object

Spy objects are related to real objects, where we don’t have to poke fun at all the methods. And the actual method calls are made for the methods that are not simulated.
For the mocked object, all methods are mocked, and here we don’t need real objects.

When we use a mock we need to create a mock object first. Next, we specify what should be returned using when-then. In this case, it does nothing with the real class.

List mockedList = Mockito.mock (List.class);

Mockito.when (mockedList.get (0)). ThenReturn (“Test”);

assertEquals (“Test”, mockedList.get (0));

When we use spy, because it is linked to a real object, when we use when (spyobject.method ()). ThenReturn (value), the real method on the spy object is called. Even when we try to laugh at the behavior.

If we mock the method on the spied object using when-then, the real method is called but the mocked value is returned. This can cause an exception because some fields can be null.

List spiedList = Mockito.spy (List.class);

Mockito.when (mockedList.get (0)). ThenReturn (“Test”);

The actual get (0) method is called on the list and this throws java.lang.IndexOutOfBoundsException: Index: 0, Size: 0

The correct way to solve this problem is to use doReturn-when

List<String> spiedList = Mockito.spy(ArrayList.class);
Mockito.doReturn("Test").when(spiedList).get(0);
assertEquals("Test", spiedList.get(0));

To note: The actual method is called only for spy class objects and not for spy interfaces.

The following code works fine because we are using Interface to spy and not the object.

List<String> spiedList = Mockito.spy(List.class);
Mockito.when(spiedList.get(0)).thenReturn("Test");

Mocking Void Method

Mocking Void Method is different from other methods. For the mock void method, there is no when-then option. We need to use the do-when option.

Example of mockery

List<String> mockedList = Mockito.mock(List.class);
Mockito.doNothing().when(mockedList).clear();

Spy example

List<String> spiedList = Mockito.spy(ArrayList.class);
spiedList.add("Test"); 
Mockito.doNothing().when(spiedList).clear(); 
spiedList.clear(); 
assertEquals("Test", spiedList.get(0));

Fast reading

  • In the Mockito method, we make fun of the use of “when-then” or “do-when”
  • In most cases when-then is used because it provides more readability with return type validation
  • Mocking methods of the spy object using the ‘when-then’ option could lead to an exception, so the ‘do-when’ option should be used
  • To make fun of cancellation methods, there is no “when-then” option.
  • The actual method of the spy object is called if the when-then option is used to mock the method, but the simulated value is returned

Reference

Related topics:

Posted on Java Code Geeks courtesy of Stacktraceguru, partner of our JCG program. See the original article here: Mockito when-then vs do-when

The opinions expressed by contributors to Java Code Geeks are their own.



Source link