The assertThrows
method in JUnit is used to assert that a block of code throws a specific type of exception. JUnit provides several overloaded versions of this method to handle different scenarios and to provide custom messages for test failures. This guide covers the basics of using the assertThrows
method, including its syntax and examples of its different overloads.
Table of Contents
- Introduction
assertThrows
Method Syntax- Examples
- Basic Usage
- Using a Custom Message
- Using a Message Supplier
- Real-World Use Case
- Conclusion
Introduction
The assertThrows
method in JUnit is an assertion method used to verify that a given block of code throws a specific type of exception. If the code does not throw the expected exception, the assertion fails, and the test is marked as failed. This method is fundamental for writing unit tests that check for the occurrence of exceptions in your code.
assertThrows Method Syntax
Here is the basic syntax of the assertThrows
method with its different overloads:
// Asserts that the supplied executable throws an exception of the expected type and returns the exception
static <T extends Throwable> T assertThrows(Class<T> expectedType, Executable executable);
// Asserts that the supplied executable throws an exception of the expected type and returns the exception with a custom message
static <T extends Throwable> T assertThrows(Class<T> expectedType, Executable executable, String message);
// Asserts that the supplied executable throws an exception of the expected type and returns the exception with a custom message supplier
static <T extends Throwable> T assertThrows(Class<T> expectedType, Executable executable, Supplier<String> messageSupplier);
Parameters:
expectedType
: The expected type of the exception.executable
: The block of code to be executed.message
: Optional. A custom message to display if the assertion fails.messageSupplier
: Optional. A supplier that provides a custom message to display if the assertion fails.
Returns:
- The exception thrown by the executable if it matches the expected type.
Examples
Basic Usage
Verify that a block of code throws a specific type of exception.
Example
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
public class ExceptionTest {
@Test
void testThrowsException() {
assertThrows(IllegalArgumentException.class, () -> {
throw new IllegalArgumentException("Invalid argument");
});
}
}
Using a Custom Message
Include a custom message to display if the assertion fails.
Example
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
public class CustomMessageTest {
@Test
void testThrowsExceptionWithMessage() {
assertThrows(IllegalArgumentException.class, () -> {
throw new IllegalArgumentException("Invalid argument");
}, "Expected IllegalArgumentException to be thrown");
}
}
Using a Message Supplier
Use a message supplier to lazily generate a custom message if the assertion fails.
Example
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
import java.util.function.Supplier;
public class MessageSupplierTest {
@Test
void testThrowsExceptionWithMessageSupplier() {
Supplier<String> messageSupplier = () -> "Expected IllegalArgumentException to be thrown";
assertThrows(IllegalArgumentException.class, () -> {
throw new IllegalArgumentException("Invalid argument");
}, messageSupplier);
}
}
Real-World Use Case
Testing a UserService Class
A common use case for assertThrows
is testing methods that are expected to throw exceptions in a UserService
class. For example, verifying that a method throws an exception when a user is not found.
Class Under Test – UserService
class UserNotFoundException extends RuntimeException {
public UserNotFoundException(String message) {
super(message);
}
}
public class UserService {
public User findUserById(int id) {
if (id != 1) {
throw new UserNotFoundException("User not found");
}
return new User("John Doe");
}
}
class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Test Class – UserServiceTest
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
public class UserServiceTest {
private final UserService userService = new UserService();
@Test
void testFindUserByIdThrowsException() {
assertThrows(UserNotFoundException.class, () -> {
userService.findUserById(2);
}, "Expected UserNotFoundException to be thrown");
}
@Test
void testFindUserByIdThrowsExceptionWithMessageSupplier() {
Supplier<String> messageSupplier = () -> "Expected UserNotFoundException to be thrown";
assertThrows(UserNotFoundException.class, () -> {
userService.findUserById(2);
}, messageSupplier);
}
}
In this example, the UserServiceTest
class tests the findUserById
method of the UserService
class using assertThrows
. It includes tests to ensure that the method throws a UserNotFoundException
when a user with a given ID is not found.
Conclusion
The assertThrows
method in JUnit is used for verifying that a given block of code throws a specific type of exception in your tests. By using assertThrows
and its various overloads, you can ensure that your tests provide clear feedback when exceptions are not thrown as expected. Understanding and using the assertThrows
method effectively is crucial for developing robust and maintainable Java applications.