What if you could make your tests instantly return any result or error without waiting or failing unpredictably?
Why doReturn and doThrow in JUnit? - Purpose & Use Cases
Imagine you are testing a method that calls another method which might return a value or throw an error. You try to test this by running the real code every time.
But what if the called method depends on a database or external service? You have to wait, and sometimes it fails unpredictably.
Manually running the real method slows down tests a lot. It also makes tests unreliable because external factors can cause failures.
It is hard to test error cases because you cannot easily force the method to throw an exception.
Using doReturn and doThrow lets you control what the called method does during tests.
You can make it return a specific value or throw an exception instantly, without running the real code.
This makes tests fast, reliable, and easy to write for both success and error cases.
when(mock.method()).thenCallRealMethod(); // runs real code, slow and unpredictabledoReturn(value).when(mock).method(); // returns value instantly doThrow(new Exception()).when(mock).method(); // throws exception instantly
You can quickly and reliably test how your code handles both normal results and errors without depending on real external calls.
Testing a payment service method that calls a bank API: use doReturn to simulate a successful payment response, and doThrow to simulate a network failure, all without calling the real bank API.
doReturn lets you fake a method's return value easily.
doThrow lets you simulate exceptions to test error handling.
Both make tests faster, more reliable, and simpler to write.
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
