Fluent assertion library providing rich assertions for Java tests with expressive failure messages
—
Exception testing and ThrowableAssert for verifying exception types, messages, causes, and stack traces in test scenarios.
import static org.assertj.core.api.Assertions.*;Methods for testing that code throws expected exceptions.
// Primary exception testing methods
ThrowableAssert assertThatThrownBy(ThrowingCallable callable)
ThrowableTypeAssert assertThatExceptionOfType(Class<? extends Throwable> type)
NotThrownAssert assertThatCode(ThrowingCallable callable)
// Specific exception type shortcuts
ThrowableAssert assertThatIllegalArgumentException()
ThrowableAssert assertThatIllegalStateException()
ThrowableAssert assertThatIOException()
ThrowableAssert assertThatNullPointerException()
ThrowableAssert assertThatRuntimeException()
ThrowableAssert assertThatException()
// Failure methods
void fail(String reason)
void fail(String reason, Object... args)
void fail(String reason, Throwable realCause)
void failBecauseExceptionWasNotThrown(Class<? extends Throwable> exceptionClass)Usage examples:
// Test that exception is thrown
assertThatThrownBy(() -> {
divide(10, 0);
}).isInstanceOf(ArithmeticException.class)
.hasMessage("/ by zero");
// Test specific exception type
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> validateAge(-5))
.withMessage("Age must be positive");
// Test that no exception is thrown
assertThatCode(() -> {
validateEmail("user@domain.com");
}).doesNotThrowAnyException();
// Shortcut methods
assertThatNullPointerException()
.isThrownBy(() -> processNull(null))
.withMessage("Input cannot be null");Comprehensive assertions for thrown exceptions.
ThrowableAssert assertThat(Throwable actual)
// Exception type assertions
ThrowableAssert isInstanceOf(Class<?> type)
ThrowableAssert isNotInstanceOf(Class<?> type)
ThrowableAssert isExactlyInstanceOf(Class<?> type)
ThrowableAssert isInstanceOfAny(Class<?>... types)
// Message assertions
ThrowableAssert hasMessage(String message)
ThrowableAssert hasMessage(String message, Object... args)
ThrowableAssert hasMessageContaining(String... values)
ThrowableAssert hasMessageContainingAll(String... values)
ThrowableAssert hasMessageStartingWith(String start)
ThrowableAssert hasMessageEndingWith(String end)
ThrowableAssert hasMessageMatching(String regex)
ThrowableAssert hasMessageMatching(Pattern pattern)
ThrowableAssert hasMessageNotContaining(String... values)
ThrowableAssert hasNoCause()
// Cause assertions
ThrowableAssert hasCause(Throwable cause)
ThrowableAssert hasCauseInstanceOf(Class<? extends Throwable> type)
ThrowableAssert hasCauseExactlyInstanceOf(Class<? extends Throwable> type)
ThrowableAssert hasRootCause(Throwable rootCause)
ThrowableAssert hasRootCauseInstanceOf(Class<? extends Throwable> type)
ThrowableAssert hasRootCauseExactlyInstanceOf(Class<? extends Throwable> type)
ThrowableAssert hasRootCauseMessage(String message)
// Stack trace assertions
ThrowableAssert hasStackTraceContaining(String... values)
ThrowableAssert hasStackTraceNotContaining(String... values)
// Suppressed exceptions
ThrowableAssert hasSuppressedException(Throwable suppressedException)
ThrowableAssert hasNoSuppressedExceptions()Usage examples:
try {
riskyOperation();
fail("Expected exception was not thrown");
} catch (Exception e) {
assertThat(e)
.isInstanceOf(ServiceException.class)
.hasMessage("Service unavailable")
.hasCauseInstanceOf(IOException.class)
.hasStackTraceContaining("ServiceImpl.process");
}
// Testing exception chain
Exception cause = new IOException("Connection failed");
Exception wrapper = new ServiceException("Operation failed", cause);
assertThat(wrapper)
.hasMessage("Operation failed")
.hasCause(cause)
.hasRootCauseInstanceOf(IOException.class)
.hasRootCauseMessage("Connection failed");Type-specific exception assertions with fluent chaining.
ThrowableTypeAssert assertThatExceptionOfType(Class<? extends Throwable> type)
// ThrowableTypeAssert methods
ThrowableAssert isThrownBy(ThrowingCallable callable)
ThrowableAssert isThrownBy(ThrowingCallable callable, String description)
// Chaining with ThrowableAssert methods
ThrowableAssert withMessage(String message)
ThrowableAssert withMessageContaining(String... values)
ThrowableAssert withMessageMatching(String regex)
ThrowableAssert withCause(Throwable cause)
ThrowableAssert withCauseInstanceOf(Class<? extends Throwable> type)
ThrowableAssert withNoCause()Usage examples:
// Type-first exception testing
assertThatExceptionOfType(ValidationException.class)
.isThrownBy(() -> validator.validate(invalidData))
.withMessage("Validation failed")
.withCauseInstanceOf(IllegalArgumentException.class);
// Multiple exception scenarios
assertThatExceptionOfType(TimeoutException.class)
.isThrownBy(() -> service.callWithTimeout(1000))
.withMessageContaining("timeout", "1000ms");Assertions for verifying that code does not throw exceptions.
NotThrownAssert assertThatCode(ThrowingCallable callable)
// NotThrownAssert methods
void doesNotThrowAnyException()
NotThrownAssert doesNotThrowAnyExceptionOfTypes(Class<? extends Throwable>... types)Usage examples:
// Verify no exception is thrown
assertThatCode(() -> {
validService.performOperation();
}).doesNotThrowAnyException();
// Verify specific exception types are not thrown
assertThatCode(() -> {
safeOperation();
}).doesNotThrowAnyExceptionOfTypes(
IllegalArgumentException.class,
NullPointerException.class
);Advanced patterns for exception testing scenarios.
// Custom ThrowingCallable for complex scenarios
interface ThrowingCallable {
void call() throws Throwable;
}
// Exception capture for detailed inspection
Throwable thrown = catchThrowable(() -> riskyCode())
assertThat(thrown).isInstanceOf(CustomException.class)Usage examples:
// Testing async exceptions
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
throw new RuntimeException("Async failure");
});
assertThatThrownBy(() -> future.get())
.isInstanceOf(ExecutionException.class)
.hasCauseInstanceOf(RuntimeException.class)
.hasRootCauseMessage("Async failure");
// Testing exception timing
long startTime = System.currentTimeMillis();
assertThatThrownBy(() -> {
Thread.sleep(100);
throw new TimeoutException("Too slow");
}).isInstanceOf(TimeoutException.class);
long duration = System.currentTimeMillis() - startTime;
assertThat(duration).isGreaterThanOrEqualTo(100);
// Capturing for multiple assertions
Throwable thrown = catchThrowable(() ->
processData(null, invalidConfig)
);
assertThat(thrown)
.isNotNull()
.isInstanceOf(ProcessingException.class);
// Additional assertions on the same exception
assertThat(thrown.getMessage())
.contains("configuration")
.contains("null");Factory methods for common exception scenarios.
// Exception capture
Throwable catchThrowable(ThrowingCallable callable)
Exception catchException(ThrowingCallable callable)
RuntimeException catchRuntimeException(ThrowingCallable callable)
NullPointerException catchNullPointerException(ThrowingCallable callable)
IllegalArgumentException catchIllegalArgumentException(ThrowingCallable callable)
IOException catchIOException(ThrowingCallable callable)
// Throwable of specific type
<T extends Throwable> T catchThrowableOfType(ThrowingCallable callable, Class<T> type)Usage examples:
// Capture specific exception types
IOException ioException = catchIOException(() ->
Files.readAllLines(Paths.get("nonexistent.txt"))
);
assertThat(ioException)
.isInstanceOf(NoSuchFileException.class)
.hasMessageContaining("nonexistent.txt");
// Generic capture with type specification
CustomException custom = catchThrowableOfType(
() -> service.customOperation(),
CustomException.class
);
assertThat(custom)
.isNotNull()
.extracting(CustomException::getErrorCode)
.isEqualTo("CUSTOM_001");Testing complex exception scenarios with causes and suppressed exceptions.
// Testing exception suppression (try-with-resources)
ThrowableAssert hasSuppressedException(Throwable suppressedException)
ThrowableAssert hasNoSuppressedExceptions()
ThrowableAssert hasSuppressedExceptions(Throwable... suppressedExceptions)
// Testing cause chains
ThrowableAssert getCause()
ThrowableAssert getRootCause()Usage examples:
// Testing try-with-resources exception suppression
class FailingResource implements AutoCloseable {
@Override
public void close() throws Exception {
throw new IOException("Close failed");
}
}
Exception mainException = catchException(() -> {
try (FailingResource resource = new FailingResource()) {
throw new RuntimeException("Main operation failed");
}
});
assertThat(mainException)
.isInstanceOf(RuntimeException.class)
.hasMessage("Main operation failed")
.hasSuppressedExceptions(new IOException("Close failed"));
// Testing deep exception chains
Exception level3 = new SQLException("DB connection lost");
Exception level2 = new DataAccessException("Query failed", level3);
Exception level1 = new ServiceException("Service error", level2);
assertThat(level1)
.hasCauseInstanceOf(DataAccessException.class)
.hasRootCauseInstanceOf(SQLException.class)
.hasRootCauseMessage("DB connection lost");// Core exception testing interface
interface ThrowingCallable {
void call() throws Throwable;
}
// Exception capture utilities
class ThrowableAssert extends AbstractObjectAssert<ThrowableAssert, Throwable> {
// All assertion methods for Throwable
}
class NotThrownAssert {
void doesNotThrowAnyException()
NotThrownAssert doesNotThrowAnyExceptionOfTypes(Class<? extends Throwable>... types)
}
class ThrowableTypeAssert<T extends Throwable> {
ThrowableAssert isThrownBy(ThrowingCallable callable)
ThrowableAssert isThrownBy(ThrowingCallable callable, String description)
}
// Pattern for regex matching
class Pattern {
static Pattern compile(String regex)
}
// Common exception types for shortcuts
class IllegalArgumentException extends RuntimeException {}
class IllegalStateException extends RuntimeException {}
class NullPointerException extends RuntimeException {}
class IOException extends Exception {}
class RuntimeException extends Exception {}Install with Tessl CLI
npx tessl i tessl/maven-org-assertj--assertj-core