Should you use Mockito thenReturn or thenAnswer? It depends! The thenReturn returns the same value in every method run; while the thenAnswer does not. We use the former to return hard-coded values; while we use the latter for derived values.
Mockito ThenReturn
Below is a screenshot that shows the output from thenReturn. Each of the first 4 lines uses thenReturn. The testNonRandom method returns 1 twice. The testRandom returns the same UUID twice.
Java Codes
The following codes use thenReturn.
SomeService1.java
We inject this service to another class and we want to mock its method.
1 2 3 4 5 6 7 8 9 | package com.turreta.mockito.example; public class SomeService1 { public String getSomethingRandom() { return "production code"; } } |
SomeManager.java
This calls getSomethingRandom
twice within processSomethingRandom
. The calls should print two different values. We can use this class for both Mockito thenReturn or thenAnswer.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package com.turreta.mockito.example; public class SomeManager { private SomeService1 service1; public SomeService1 getService1() { return service1; } public void setService1(SomeService1 service1) { this.service1 = service1; } void processSomethingRandom() { System.out.println("Start: In SomeManager: " + service1.getSomethingRandom()); // Print again System.out.println("End: In SomeManager: " + service1.getSomethingRandom()); } } |
Unit Test – SomeManagerTest.java
This is our Test class. It has 2 methods. One mocks another method to return a hard-coded value; while the other to return random value.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | package com.turreta.mockito.example; import static org.junit.Assert.*; import java.util.UUID; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class SomeManagerTest { @Mock private SomeService1 service1; @InjectMocks private SomeManager manager; @Test public void testNonRandom() { Mockito.when( service1.getSomethingRandom()) .thenReturn("" + 1); manager.processSomethingRandom(); } @Test public void testRandom() { Mockito.when( service1.getSomethingRandom()) .thenReturn( UUID.randomUUID().toString()); manager.processSomethingRandom(); System.out.println( "An separate call to UUID.randomUUID().toString() yields: " + UUID.randomUUID().toString()); } } |
Mockito ThenAnswer
Below is a screenshot that shows the output from thenAnswer.
Java Codes
Below are the codes using thenAnswer. They use the Answer interface. They override its single method to return a derive value. However, we can use Lamda expression.
SomeManagerTest2.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | package com.turreta.mockito.example; import java.util.UUID; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.runners.MockitoJUnitRunner; import org.mockito.stubbing.Answer; @RunWith(MockitoJUnitRunner.class) public class SomeManagerTest2 { @Mock private SomeService1 service1; @InjectMocks private SomeManager manager; @Test public void testRandomNew() { Answer<String> ans = new Answer<String>() { @Override public String answer(InvocationOnMock invocation) throws Throwable { return UUID.randomUUID().toString(); } }; Mockito.when( service1.getSomethingRandom()) .thenAnswer(ans); manager.processSomethingRandom(); System.out.println( "An separate call to UUID.randomUUID().toString() yields: " + UUID.randomUUID().toString()); } } |
Using Mockito thenReturn or thenAnswer depends on your needs. If you need work with static values, use thenReturn. If you need to use dynamic or derived values, use thenAnswer.