Enterprise Java

Mock Void method with Mockito

Hey guys! After our previous blog on difference between thenReturn and thenAnswer mockito methods, we are back with yet another interesting blog on Mockito. Here, we shall discuss “How to Mock Void method with Mockito”. Let’s get started!

When writing code, there is always at least one method that returns ‘void’, and at some point in time we need to mock ‘void’ method. So how do we go about it? Let us together figure this out in the following blog using mockito.

Mockito is one of the most famous mocking framework used for writing unit tests. If you are new to mocking you can know more at mockito website.

Why we need to mock void method?

Let’s assume we have a method. In this method we call another void method. Now, when you want to write test case for this method, how can we test that the void method was called? Also, if the correct parameters were passed to void method?
In this case mockito comes to our rescue.

Let’s take an example, we have a UserService class. In this class we have a updateName() method.

1
2
3
4
5
6
public UserService{
    ...
   public void updateName(Long id, String name){
      userRepository.updateName(id, name);
   }
}

Now, we want to write unit test for UserService class and mock userRepository.
But the only thing we need to verify in this test case is that updateName() method from userRepository is called with correct set of parameters.
For this purpose we need to mock updateName() method, capture the arguments and verify the arguments.

One of the most important point to note here is that, we can not just mock void method using when-then mechanism of mockito. Because, when() method of mockito works with return value and does not work when method is void.

How to mock void method in mockito?

In Mockito we can use different methods to call real method or mock void method. We can use one of the options as per requirements

  1. doNothing() : Completely ignore the calling of void method, this is default behavior
  2. doAnswer() : Perform some run time or complex operations when void method is called
  3. doThrow() : Throw exception when mocked void method is called
  4. doCallRealMethod() : Do not mock and call real method

1) Using doNothing()

If we just want to completely ignore the void method call, we can use doNothing().

In mocking, for every method of mocked object doNothing is the default behavior. Hence, if you don’t want to verify parameters, use of doNothing is completely optional. Following all codes perform similar behavior,

Example using doNothing() for void method

1
2
3
4
5
6
7
8
@Test
public void testUpdateNameWithDoNothingVerifyRepositoryCall() {
   doNothing().when(mockedUserRepository).updateName(anyLong(),anyString());
 
   userService.updateName(1L,"void mock test");
     
   verify(mockedUserRepository, times(1)).updateName(1L,"void mock test");
}

Without using doNothing() for void method

1
2
3
4
5
6
7
@Test
public void testUpdateNameWithOutDoNothingVerifyRepositoryCall() {
 
   userService.updateName(1L,"void mock test");
     
   verify(mockedUserRepository, times(1)).updateName(1L,"void mock test");
}

Example of argument capture using doNothing()

We can do different things with argument capture. Here, we will just verify the captured value

01
02
03
04
05
06
07
08
09
10
11
12
@Test
public void testUpdateNameUsingArgumentCaptor() {
 
   ArgumentCaptor<Long> idCapture = ArgumentCaptor.forClass(Long.class);
   ArgumentCaptor<String> nameCapture = ArgumentCaptor.forClass(String.class);
   doNothing().when(mockedUserRepository).updateName(idCapture.capture(),nameCapture.capture());
  
   userService.updateName(1L,"void mock test");
     
   assertEquals(1L, idCapture.getValue());
   assertEquals("void mock test", nameCapture.getValue());
}

2) Using doAnswer() for void method

If we do not want to call real method, however need to perform some runtime operation doAnswer is used.

Let’s take an example of doAnswer where we will print and verify the argument using doAnswer

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
@Test
public void testUpdateNameUsingDoAnswer() {
   doAnswer(invocation -> {
      long id = invocation.getArgument(0);
      String name = invocation.getArgument(1);
      System.out.println("called for id: "+id+" and name: "+name);
 
      assertEquals(1L, id);
      assertEquals("void mock test", name);
 
      return null;
}).when(mockedUserRepository).updateName(anyLong(),anyString());
 
   userService.updateName(1L,"void mock test");
   verify(mockedUserRepository, times(1)).updateName(1L,"void mock test");
}

3) Throw exception using doThrow()

If we want to throw an exception when method is called, we can use doThrow() method of mockito.

Let’s take an example where we will throw InvalidParamException when updateName() method is called with null id.

1
2
3
4
5
6
@Test(expected = InvalidParamException.class)
public void testUpdateNameThrowExceptionWhenIdNull() {
   doThrow(new InvalidParamException())
      .when(mockedUserRepository).updateName(null,anyString();
   userService.updateName(null,"void mock test");
}

4) Real method call using doCallRealMethod()

Sometimes it is necessary to call the real method from mocked object, in such case we need to use doCallRealMethod(), because doNothig() is the default behavior.

In the following example real method from userRepository will be called even though it is a mocked object.

1
2
3
4
5
6
7
8
9
@Test
public void testUpdateNameCallRealRepositoryMethod() {
 
   doCallRealMethod().when(mockedUserRepository).updateName(anyLong(), anyString());
  
   userService.updateName(1L,"calling real method");
  
   verify(mockedUserRepository, times(1)).add(1L,"calling real method");
}

Fast track reading

Published on Java Code Geeks with permission by Stacktraceguru, partner at our JCG program. See the original article here: Mock Void method with Mockito

Opinions expressed by Java Code Geeks contributors are their own.

Stacktraceguru

Stacktraceguru is an educational website. This website helps software programmers to learn and clarify concepts.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Nirali
Nirali
2 months ago

I am new for Unit test and Mockito.
In doNothing, I am not able to initialization for mockedUserRepository.
I tried below code but not working



public void testForGenerateToken() throws InvalidKeyException, IllegalArgumentException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {

String userIdMock=“String”;
String emailAddressMock=“String”;

ForgotPasswordPAStepTwoController stepTwoControllerMock = mock(ForgotPasswordPAStepTwoController.class, “myMock”);

when(user.getUserId()).thenReturn(userIdMock);
when(user.getEmailAddress()).thenReturn(emailAddressMock);
doNothing().when(stepTwoControllerMock).reset();

String tokenGenerated=forgotPasswordPAStepTwoController.generateToken();
assertEquals(tokenGenerated,notNull());
}

Back to top button