The doThrow
method in Mockito is used to stub void methods with exceptions. This is useful when you want to simulate error conditions or exceptional scenarios in your tests. The doThrow
method has several overloaded versions to handle different cases, including setting up consecutive exceptions.
Table of Contents
- Introduction
doThrow
Method Syntax- Examples
- Basic Usage
- Setting Consecutive Exceptions with Exception Classes
- Setting Consecutive Exceptions with Throwable Instances
- Real-World Use Case
- Conclusion
Introduction
Mockito is a popular library in Java for creating and managing mock objects. The doThrow
method allows you to stub void methods to throw exceptions. This is particularly useful for testing how your code handles error conditions and exceptions.
doThrow Method Syntax
Throwing a Single Exception
static Stubber doThrow(Class<? extends Throwable> toBeThrown)
Stubs the void method to throw the specified exception class.
Throwing Consecutive Exceptions with Exception Classes
static Stubber doThrow(Class<? extends Throwable> toBeThrown, Class<? extends Throwable>... toBeThrownNext)
Stubs the void method to throw the specified exception classes consecutively.
Throwing Consecutive Exceptions with Throwable Instances
static Stubber doThrow(Throwable... toBeThrown)
Stubs the void method to throw the specified Throwable instances consecutively.
Examples
Basic Usage
Stub a void method to throw a single exception.
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.doThrow;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class BasicDoThrowTest {
@Test
void testDoThrow() {
UserService mockUserService = mock(UserService.class);
// Stub the deleteUser method to throw RuntimeException
doThrow(RuntimeException.class).when(mockUserService).deleteUser("123");
// Verify that the method throws the expected exception
assertThrows(RuntimeException.class, () -> mockUserService.deleteUser("123"));
}
}
class UserService {
public void deleteUser(String userId) {
// Method implementation
}
}
Setting Consecutive Exceptions with Exception Classes
Stub a void method to throw different exceptions on consecutive calls.
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.doThrow;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class ConsecutiveDoThrowTest {
@Test
void testDoThrowConsecutiveExceptions() {
UserService mockUserService = mock(UserService.class);
// Stub the deleteUser method to throw different exceptions on consecutive calls
doThrow(IllegalArgumentException.class, IllegalStateException.class).when(mockUserService).deleteUser("123");
// Verify that the method throws the expected exceptions
assertThrows(IllegalArgumentException.class, () -> mockUserService.deleteUser("123"));
assertThrows(IllegalStateException.class, () -> mockUserService.deleteUser("123"));
}
}
class UserService {
public void deleteUser(String userId) {
// Method implementation
}
}
Setting Consecutive Exceptions with Throwable Instances
Stub a void method to throw different Throwable instances on consecutive calls.
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.doThrow;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class ThrowableDoThrowTest {
@Test
void testDoThrowWithThrowableInstances() {
UserService mockUserService = mock(UserService.class);
// Stub the deleteUser method to throw different Throwable instances on consecutive calls
doThrow(new RuntimeException("First exception"), new RuntimeException("Second exception")).when(mockUserService).deleteUser("123");
// Verify that the method throws the expected exceptions
assertThrows(RuntimeException.class, () -> mockUserService.deleteUser("123"), "First exception");
assertThrows(RuntimeException.class, () -> mockUserService.deleteUser("123"), "Second exception");
}
}
class UserService {
public void deleteUser(String userId) {
// Method implementation
}
}
Real-World Use Case
Testing Error Handling in a Service
In a real-world scenario, you might have a service class that needs to handle exceptions from its dependencies. Using Mockito, you can stub the methods of these dependencies to throw exceptions and test how your service class handles them.
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.doThrow;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
class User {
private String id;
private String name;
public User(String id, String name) {
this.id = id;
this.name = name;
}
public String getName() {
return name;
}
}
interface UserRepository {
void deleteUser(String id);
}
class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void deleteUser(String userId) {
userRepository.deleteUser(userId);
}
}
public class UserServiceTest {
@Test
void testDeleteUserExceptionHandling() {
UserRepository mockUserRepository = mock(UserRepository.class);
UserService userService = new UserService(mockUserRepository);
// Stub the deleteUser method to throw an exception
doThrow(new RuntimeException("User not found")).when(mockUserRepository).deleteUser("123");
// Verify that the deleteUser method throws the expected exception
assertThrows(RuntimeException.class, () -> userService.deleteUser("123"), "User not found");
}
}
In this example, the UserServiceTest
class uses Mockito’s doThrow
method to stub the deleteUser
method of the UserRepository
interface. The test verifies that the UserService
correctly handles the exception thrown by the UserRepository
.
Conclusion
The doThrow
method in Mockito is used for stubbing void methods to throw exceptions. By using doThrow
, you can simulate error conditions and test how your code handles exceptions. This helps ensure that your tests are comprehensive and cover a wide range of scenarios, including exceptional ones.