The thenThrow method in the Mockito framework is used to configure mock objects to throw exceptions when specific methods are called. This is particularly useful for testing how your code handles exceptions. The method belongs to the OngoingStubbing interface, which is used to configure the behavior of mock methods.
Table of Contents
- Introduction
thenThrowMethod Syntax- Examples
- Basic Usage with a Single Throwable Class
- Setting Consecutive Throwable Classes
- Setting Consecutive Throwable Objects
- Real-World Use Case
- Conclusion
Introduction
Mockito is a popular library in Java for creating and managing mock objects. The thenThrow method, which belongs to the OngoingStubbing interface, allows you to specify exceptions that should be thrown when a method is called. This can be useful for testing error handling in your code.
thenThrow Method Syntax
Throwing a Single Throwable Class
import org.mockito.stubbing.OngoingStubbing;
OngoingStubbing<T> thenThrow(Class<? extends Throwable> throwableType)
Sets a Throwable type to be thrown when the method is called.
Throwing Consecutive Throwable Classes
import org.mockito.stubbing.OngoingStubbing;
OngoingStubbing<T> thenThrow(Class<? extends Throwable> toBeThrown, Class<? extends Throwable>... nextToBeThrown)
Sets Throwable classes to be thrown when the method is called.
Throwing Consecutive Throwable Objects
import org.mockito.stubbing.OngoingStubbing;
OngoingStubbing<T> thenThrow(Throwable... throwables)
Sets Throwable objects to be thrown when the method is called.
Parameters:
throwableType: TheThrowableclass to be thrown.toBeThrown: The firstThrowableclass to be thrown.nextToBeThrown: AdditionalThrowableclasses to be thrown consecutively.throwables:Throwableobjects to be thrown consecutively.
Returns:
- An
OngoingStubbingobject that allows further configuration of the stubbed method.
Examples
Basic Usage with a Single Throwable Class
Set a single Throwable class to be thrown for a stubbed method.
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
public class BasicThenThrowTest {
@Test
void testThenThrow() {
UserService mockUserService = mock(UserService.class);
// Set a Throwable class to be thrown
when(mockUserService.getUserDetails(anyString())).thenThrow(IllegalArgumentException.class);
// Call the method and verify the exception
try {
mockUserService.getUserDetails("123");
} catch (IllegalArgumentException e) {
assertEquals(IllegalArgumentException.class, e.getClass());
}
}
}
class UserService {
public String getUserDetails(String userId) {
return "Real user details for " + userId;
}
}
Setting Consecutive Throwable Classes
Set consecutive Throwable classes to be thrown for a stubbed method.
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
public class ConsecutiveThenThrowTest {
@Test
void testConsecutiveThenThrow() {
UserService mockUserService = mock(UserService.class);
// Set consecutive Throwable classes to be thrown
when(mockUserService.getUserDetails(anyString())).thenThrow(IllegalArgumentException.class, NullPointerException.class);
// Call the method multiple times and verify the exceptions
try {
mockUserService.getUserDetails("123");
} catch (IllegalArgumentException e) {
assertEquals(IllegalArgumentException.class, e.getClass());
}
try {
mockUserService.getUserDetails("123");
} catch (NullPointerException e) {
assertEquals(NullPointerException.class, e.getClass());
}
}
}
class UserService {
public String getUserDetails(String userId) {
return "Real user details for " + userId;
}
}
Setting Consecutive Throwable Objects
Set consecutive Throwable objects to be thrown for a stubbed method.
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
public class ConsecutiveThenThrowObjectsTest {
@Test
void testConsecutiveThenThrowObjects() {
UserService mockUserService = mock(UserService.class);
// Set consecutive Throwable objects to be thrown
when(mockUserService.getUserDetails(anyString())).thenThrow(new IllegalArgumentException("Invalid argument"), new NullPointerException("Null pointer"));
// Call the method multiple times and verify the exceptions
try {
mockUserService.getUserDetails("123");
} catch (IllegalArgumentException e) {
assertEquals("Invalid argument", e.getMessage());
}
try {
mockUserService.getUserDetails("123");
} catch (NullPointerException e) {
assertEquals("Null pointer", e.getMessage());
}
}
}
class UserService {
public String getUserDetails(String userId) {
return "Real user details for " + userId;
}
}
Real-World Use Case
Testing Error Handling in Services
In a real-world scenario, you might need to test how your service handles exceptions. The thenThrow method allows you to simulate various error conditions and verify that your service responds appropriately.
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
interface PaymentService {
void processPayment(String orderId) throws Exception;
}
class PaymentServiceImpl implements PaymentService {
public void processPayment(String orderId) {
// Real implementation
}
}
public class PaymentServiceTest {
@Test
void testProcessPayment() {
PaymentService mockPaymentService = mock(PaymentService.class);
// Set Throwable classes to be thrown
doThrow(new IllegalStateException("Service unavailable")).when(mockPaymentService).processPayment("123");
// Call the method and verify the exception
Exception exception = assertThrows(IllegalStateException.class, () -> {
mockPaymentService.processPayment("123");
});
assertEquals("Service unavailable", exception.getMessage());
}
}
In this example, the PaymentServiceTest class uses Mockito’s thenThrow method to simulate an IllegalStateException when the processPayment method is called. This allows the test to verify that the service correctly handles the exception.
Conclusion
The thenThrow method in Mockito is used for configuring mock objects to throw exceptions. By using thenThrow, you can specify exceptions that should be thrown when a method is called, allowing you to test how your code handles various error conditions. This helps ensure that your tests are accurate and comprehensive, allowing you to validate both normal and exceptional behavior.