In this article, we’ll explain how to mock throw exceptions in Mockito, with real-world examples, use cases, and best practices.
What is Mockito?
Mockito is a Java-based mocking framework used in unit testing. It allows you to create mock objects of classes or interfaces and define behaviors for them without requiring the actual implementation. This enables isolated testing, faster execution, and easier debugging.
Mockito is commonly used alongside testing frameworks like JUnit and TestNG.
Why Mock an Exception?
Mocking exceptions is useful for testing how a class or method behaves when something goes wrong. For example:
- An API call fails and throws a RuntimeException
- A database connection is interrupted and throws an SQLException
- A service returns a null pointer or timeout
Testing such scenarios helps ensure your code handles failures gracefully.
Basic Syntax: Mock Throw Exception in Mockito
Mockito provides the thenThrow() method to simulate an exception when a mocked method is invoked.
Basic syntax:
when(mockedObject.method()).thenThrow(new ExceptionType("message"));
Or using doThrow() for void methods:
doThrow(new ExceptionType("message")).when(mockedObject).voidMethod();
Example 1: Mock Throw Exception for Non-Void Method
Let’s say we have a simple UserService class that calls a method in UserRepository:
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository repo) {
this.userRepository = repo;
}
public User findUser(String id) {
return userRepository.getUserById(id);
}
}
Now, suppose getUserById() throws a RuntimeException if the user is not found.
Test with mocked exception:
@Test(expected = RuntimeException.class)
public void testFindUser_throwsException() {
UserRepository mockRepo = mock(UserRepository.class);
when(mockRepo.getUserById("123")).thenThrow(new RuntimeException("User not found"));
UserService service = new UserService(mockRepo);
service.findUser("123"); // This should throw the exception
}
Example 2: Mock Throw Exception for Void Method
If your method returns void, you can't use when().thenThrow(). Instead, use doThrow():
public class NotificationService {
public void sendEmail(String email) {
// logic to send email
}
}
Test:
@Test
public void testSendEmail_throwsException() {
NotificationService mockService = mock(NotificationService.class);
doThrow(new IllegalStateException("Mail server error"))
.when(mockService).sendEmail("[email protected]");
Assertions.assertThrows(IllegalStateException.class, () -> {
mockService.sendEmail("[email protected]");
});
}
Mocking Multiple Exceptions
Mockito also supports throwing multiple exceptions in sequence:
when(mockRepo.getUserById("123"))
.thenThrow(new RuntimeException("First"))
.thenThrow(new IllegalArgumentException("Second"));
Each call will throw the next exception in the sequence.
Using doAnswer() for Custom Exceptions
If you want conditional behavior or custom logic when throwing an exception, use doAnswer():
when(mockRepo.getUserById(anyString())).thenAnswer(invocation -> {
String id = invocation.getArgument(0);
if (id.equals("123")) {
throw new RuntimeException("User not found");
}
return new User(id, "Jane");
});
This is helpful when testing complex branching logic.
Best Practices
- Use thenThrow() for readable and simple test cases where you want to simulate a straightforward failure.
- Use doThrow() only for void methods.
- Always assert the exception type and message to ensure proper behavior.
- Avoid overusing mocking—mocking every dependency can lead to fragile tests.
- Prefer interfaces for mocking instead of concrete classes for better test isolation.
Common Mistakes to Avoid
- Using when().thenThrow() for void methods — this will compile but silently fail. Use doThrow() instead.
- Forgetting to annotate the test with @Test(expected = Exception.class) or using assertThrows() — the test will pass even if the exception isn’t thrown.
- Over-mocking or mocking things that don’t need to be mocked (e.g., simple data models).
Final Thoughts
Mockito’s ability to simulate exceptions is one of its most powerful features. Whether you're testing error handling, retry logic, or fallback mechanisms, learning how to mock throw exceptions in Mockito effectively can drastically improve your test coverage and application robustness.
To recap:
- Use thenThrow() for regular methods
- Use doThrow() for void methods
- Use doAnswer() for custom logic
- Always test both normal and exceptional flows
By mastering these techniques, you’ll write more resilient, maintainable Java applications.
Read more on- https://keploy.io/blog/community/simplifying-junit-test-stubs-and-mocking