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
thenThrow
Method 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
: TheThrowable
class to be thrown.toBeThrown
: The firstThrowable
class to be thrown.nextToBeThrown
: AdditionalThrowable
classes to be thrown consecutively.throwables
:Throwable
objects to be thrown consecutively.
Returns:
- An
OngoingStubbing
object 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.