when().thenThrow() for exceptions in JUnit - Build an Automation Script
import static org.mockito.Mockito.when; 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; class Dependency { String getData() { return "real data"; } } class Service { private final Dependency dependency; Service(Dependency dependency) { this.dependency = dependency; } String fetchData() { return dependency.getData(); } } @ExtendWith(MockitoExtension.class) public class ServiceTest { @Mock Dependency dependency; @InjectMocks Service service; @Test void fetchData_shouldThrowException_whenDependencyThrows() { when(dependency.getData()).thenThrow(new RuntimeException("Dependency failure")); RuntimeException thrown = assertThrows(RuntimeException.class, () -> { service.fetchData(); }); // Optional: verify exception message org.junit.jupiter.api.Assertions.assertEquals("Dependency failure", thrown.getMessage()); } }
This test uses Mockito to mock the Dependency class. The when().thenThrow() method tells Mockito to throw a RuntimeException when getData() is called.
The assertThrows method from JUnit 5 checks that the exception is actually thrown when service.fetchData() is called. This is cleaner and clearer than using try-catch blocks.
Annotations @Mock and @InjectMocks set up the test objects automatically. The @ExtendWith(MockitoExtension.class) enables Mockito support in JUnit 5.
This approach ensures the test fails if the exception is not thrown, making the test reliable and easy to understand.
Now add data-driven testing with 3 different exceptions thrown by the dependency
Practice
when().thenThrow() in JUnit tests?Solution
Step 1: Understand the role of
This syntax is used in mocking frameworks like Mockito to simulate exceptions when a mocked method is called.when().thenThrow()Step 2: Identify the purpose in testing
It helps test how your code handles exceptions by forcing the mocked method to throw an exception.Final Answer:
To simulate an exception being thrown by a mocked method -> Option DQuick Check:
Exception simulation [OK]
- Confusing exception simulation with return value mocking
- Thinking it creates real exceptions instead of simulated ones
- Using it to skip tests instead of throwing exceptions
IllegalArgumentException using Mockito?Solution
Step 1: Recall Mockito syntax for throwing exceptions
The correct syntax useswhen(mock.method()).thenThrow(new ExceptionType()).Step 2: Match the options with correct syntax
when(mock.method()).thenThrow(new IllegalArgumentException()) matches the correct syntax exactly, creating a new exception instance insidethenThrow().Final Answer:
when(mock.method()).thenThrow(new IllegalArgumentException()) -> Option BQuick Check:
Correct Mockito exception syntax [OK]
- Using throwException or throws which are not Mockito methods
- Not creating a new exception instance
- Calling thenThrow directly on mock.method()
MyService mockService = mock(MyService.class);
when(mockService.getData()).thenThrow(new RuntimeException("Error"));
assertThrows(RuntimeException.class, () -> mockService.getData());Solution
Step 1: Analyze the mocking behavior
The mocked methodgetData()is set to throw aRuntimeExceptionwhen called.Step 2: Understand the assertion
assertThrowsexpects aRuntimeExceptionfrom callingmockService.getData().Final Answer:
Test passes because RuntimeException is thrown as expected -> Option AQuick Check:
Exception thrown matches assertThrows [OK]
- Assuming no exception is thrown from mocked method
- Confusing exception types in assertThrows
- Thinking thenThrow causes syntax errors
when(mockService.getData()).thenThrow(RuntimeException.class); assertThrows(RuntimeException.class, () -> mockService.getData());
Solution
Step 1: Check thenThrow argument type
thenThrowrequires an exception instance, not a class type.Step 2: Identify correct usage
The code should usethenThrow(new RuntimeException())instead of passing the class.Final Answer:
Incorrect use of thenThrow with exception class instead of instance -> Option CQuick Check:
thenThrow needs exception instance [OK]
- Passing exception class instead of instance to thenThrow
- Expecting assertThrows to catch exceptions without mocking
- Adding unnecessary try-catch in test
NullPointerException thrown by a dependency's void call() method. Which of the following code snippets correctly mocks the dependency and verifies the exception handling using JUnit and Mockito?Solution
Step 1: Understand mocking exceptions with void methods
Ifdependency.call()is a void method,doThrow().when()is the correct way to mock exceptions.Step 2: Verify correct assertion
assertThrows(NullPointerException.class, () -> service.callDependency())correctly checks that the service handles the exception.Step 3: Analyze options
when(dependency.call()).thenThrow(new NullPointerException()); assertThrows(NullPointerException.class, () -> service.callDependency()); useswhen().thenThrow()which works only for non-void methods. when(dependency.call()).thenThrow(NullPointerException.class); assertThrows(Exception.class, () -> service.callDependency()); passes class instead of instance and wrong exception type in assertion. when(dependency.call()).thenReturn(null); assertThrows(NullPointerException.class, () -> service.callDependency()); returns null instead of throwing exception.Final Answer:
doThrow(new NullPointerException()).when(dependency).call(); assertThrows(NullPointerException.class, () -> service.callDependency()); -> Option AQuick Check:
Use doThrow for void methods + assertThrows [OK]
- Using thenThrow() on void methods
- Passing exception class instead of instance
- Asserting wrong exception type
- Returning null instead of throwing exception
Ready to prove it?
Pass the test and this pattern moves unknown
