doReturn and doThrow in JUnit - Build an Automation Script
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) public class ServiceTest { @Mock Dependency dependency; @InjectMocks Service service; @Test void testDoReturn() { // Arrange doReturn("mocked response").when(dependency).getData(); // Act String result = service.processData(); // Assert assertEquals("mocked response", result); } @Test void testDoThrow() { // Arrange doThrow(new RuntimeException("mocked exception")).when(dependency).getData(); // Act & Assert RuntimeException thrown = assertThrows(RuntimeException.class, () -> { service.processData(); }); assertEquals("mocked exception", thrown.getMessage()); } } // Supporting classes class Service { private final Dependency dependency; public Service(Dependency dependency) { this.dependency = dependency; } public String processData() { return dependency.getData(); } } interface Dependency { String getData(); }
This test class uses JUnit 5 and Mockito to automate the manual test case steps.
Annotations: @ExtendWith(MockitoExtension.class) enables Mockito support. @Mock creates a mock for the dependency. @InjectMocks injects the mock into the service.
testDoReturn: Uses doReturn to mock dependency.getData() to return "mocked response". Then calls service.processData() and asserts the returned value matches.
testDoThrow: Uses doThrow to mock dependency.getData() to throw a RuntimeException. Then asserts that calling service.processData() throws the expected exception with the correct message.
This approach clearly separates setup, action, and verification steps, making the test easy to read and maintain.
Now add data-driven testing with 3 different return values and 3 different exceptions for the mocked method
Practice
doReturn in JUnit mocking?Solution
Step 1: Understand
doReturnusagedoReturnis used to tell a mock what value to return when a specific method is called.Step 2: Differentiate from
doThrowdoThrowmakes the method throw an exception, not return a value.Final Answer:
To specify a value that a mocked method should return when called -> Option AQuick Check:
doReturnsets return value [OK]
- Confusing doReturn with doThrow
- Thinking doReturn verifies method calls
- Assuming doReturn resets mocks
doThrow?Solution
Step 1: Recall correct
The correct syntax isdoThrowsyntaxdoThrow(new ExceptionType()).when(mock).method();to specify the exception and method.Step 2: Check each option
doThrow(new IOException()).when(mockObject).methodName(); matches the correct syntax exactly. Others have misplaced parentheses or wrong order.Final Answer:
doThrow(new IOException()).when(mockObject).methodName(); -> Option CQuick Check:
CorrectdoThrowsyntax = doThrow(new IOException()).when(mockObject).methodName(); [OK]
- Omitting 'new' before exception
- Placing parentheses incorrectly
- Calling method before when()
mockService.getData() is called?
MyService mockService = mock(MyService.class);
doReturn("Hello").when(mockService).getData();
doThrow(new RuntimeException()).when(mockService).getData();
System.out.println(mockService.getData());Solution
Step 1: Analyze the order of stubbing
FirstdoReturn("Hello")is set, thendoThrow(RuntimeException)overrides it for the same method.Step 2: Determine which stub applies on method call
The last stubdoThrowtakes effect, so callinggetData()throws RuntimeException.Final Answer:
RuntimeException is thrown -> Option BQuick Check:
Last stub wins, so exception thrown [OK]
- Assuming first stub applies
- Expecting returned string instead of exception
- Thinking code won't compile
doReturn and doThrow:
doReturn("Success").when(mockService).process();
doThrow(new IllegalArgumentException()).when(mockService).process();
doReturn("Done").when(mockService).process();
String result = mockService.process();Solution
Step 1: Understand stub overriding order
Stubs are applied in order; the last stub for a method is effective.Step 2: Check the last stub
The last stub isdoReturn("Done"), so callingprocess()returns "Done" without exception.Final Answer:
The last doReturn overrides previous stubs, so no error -> Option DQuick Check:
Last stub wins, no exception thrown [OK]
- Thinking doThrow always throws exception regardless of order
- Believing mixing doReturn and doThrow causes compile error
- Expecting exception thrown despite last stub
externalService.fetch(). You want to simulate two calls: the first returns "Data1", the second throws an IOException. Which is the correct way to stub fetch() using doReturn and doThrow?Solution
Step 1: Understand chaining stubs for multiple calls
Mockito allows chaining stubs withdoReturn(...).doThrow(...).when(mock).method();to simulate sequential calls.Step 2: Analyze options
doReturn("Data1").doThrow(new IOException()).when(externalService).fetch();correctly chainsdoReturnthendoThrowfor first return and second throw. SeparatedoReturn("Data1").when(externalService).fetch(); doThrow(new IOException()).when(externalService).fetch();overrides stubs, causing all calls to throw the exception. The other options use repeated returns or incorrect order.Final Answer:
doReturn("Data1").doThrow(new IOException()).when(externalService).fetch(); -> Option AQuick Check:
Chain doReturn then doThrow for sequential calls [OK]
- Overwriting stubs instead of chaining
- Wrong order of doThrow and doReturn
- Expecting multiple when() calls for sequence
Ready to prove it?
Pass the test and this pattern moves unknown
