CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-assertj--assertj-core

Fluent assertion library providing rich assertions for Java tests with expressive failure messages

Pending
Overview
Eval results
Files

advanced.mddocs/

Advanced Features

Advanced AssertJ features including filters, groups, atomic types, concurrent types, predicates, streams, file system operations, and specialized utilities.

Core Imports

import static org.assertj.core.api.Assertions.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.*;
import java.util.stream.*;
import java.nio.file.*;
import java.util.function.*;

Capabilities

Assumptions

Assumptions for conditional test execution, allowing tests to be skipped when certain conditions are not met.

// AssertJ assumptions for conditional assertions
import static org.assertj.core.api.Assumptions.*;

// JUnit 5 style assumptions for conditional test execution  
import static org.assertj.core.api.Assumptions.assumeThat;

// AssertJ assume methods
ObjectAssert<T> assumeThat(T actual)
BooleanAssert assumeThat(boolean actual)
StringAssert assumeThat(String actual)
IntegerAssert assumeThat(int actual)
ListAssert<T> assumeThat(List<T> actual)

// Assumption failure handling
void assumingThat(boolean assumption, ThrowingCallable executable)
void assumingThat(boolean assumption, Runnable executable)

Usage examples:

// Basic assumptions - skip test if assumption fails
@Test
void testOnlyOnWindows() {
    assumeThat(System.getProperty("os.name"))
        .startsWith("Windows");
    
    // Test code that only runs on Windows
    assertThat(windowsSpecificFeature()).isTrue();
}

@Test  
void testWithMinimumJavaVersion() {
    assumeThat(System.getProperty("java.version"))
        .satisfies(version -> {
            String[] parts = version.split("\\.");
            int major = Integer.parseInt(parts[0]);
            return major >= 11;
        });
    
    // Test code that requires Java 11+
    assertThat(modernJavaFeature()).isNotNull();
}

// Conditional execution within test
@Test
void testWithOptionalFeature() {
    boolean featureEnabled = isFeatureEnabled();
    
    assumingThat(featureEnabled, () -> {
        // This code only runs if feature is enabled
        assertThat(getFeatureResult()).isEqualTo("expected");
    });
    
    // This always runs regardless of assumption
    assertThat(basicFunctionality()).isTrue();
}

// Collection assumptions
@Test
void testWithNonEmptyList() {
    List<String> items = getItems();
    assumeThat(items).isNotEmpty();
    
    // Test code that requires non-empty list
    assertThat(processItems(items)).hasSize(items.size());
}

// Numeric assumptions  
@Test
void testWithPositiveValue() {
    int value = getValue();
    assumeThat(value).isPositive();
    
    // Test code that requires positive value
    assertThat(calculateSquareRoot(value)).isGreaterThan(0);
}

Atomic Type Assertions

Assertions for java.util.concurrent.atomic types ensuring thread-safe value verification.

// Atomic reference types
AtomicReferenceAssert<T> assertThat(AtomicReference<T> actual)
AtomicReferenceArrayAssert<T> assertThat(AtomicReferenceArray<T> actual)
AtomicReferenceFieldUpdaterAssert<OBJECT, FIELD> assertThat(AtomicReferenceFieldUpdater<OBJECT, FIELD> actual)

// Atomic numeric types
AtomicIntegerAssert assertThat(AtomicInteger actual)
AtomicLongAssert assertThat(AtomicLong actual)
AtomicBooleanAssert assertThat(AtomicBoolean actual)

// Atomic array types
AtomicIntegerArrayAssert assertThat(AtomicIntegerArray actual)
AtomicLongArrayAssert assertThat(AtomicLongArray actual)

// Atomic field updaters
AtomicIntegerFieldUpdaterAssert<OBJECT> assertThat(AtomicIntegerFieldUpdater<OBJECT> actual)
AtomicLongFieldUpdaterAssert<OBJECT> assertThat(AtomicLongFieldUpdater<OBJECT> actual)

// Atomic marked/stamped references
AtomicMarkableReferenceAssert<T> assertThat(AtomicMarkableReference<T> actual)
AtomicStampedReferenceAssert<T> assertThat(AtomicStampedReference<T> actual)

// Long adders
LongAdderAssert assertThat(LongAdder actual)

Usage examples:

// Atomic references
AtomicReference<String> atomicString = new AtomicReference<>("initial");
assertThat(atomicString)
    .hasValue("initial")
    .doesNotHaveValue("other");

AtomicInteger counter = new AtomicInteger(42);
assertThat(counter)
    .hasValue(42)
    .hasPositiveValue()
    .hasValueBetween(40, 45);

// Atomic arrays
AtomicIntegerArray atomicArray = new AtomicIntegerArray(new int[]{1, 2, 3});
assertThat(atomicArray)
    .hasArray(new int[]{1, 2, 3})
    .hasSize(3);

// Atomic markable reference
AtomicMarkableReference<String> markableRef = new AtomicMarkableReference<>("value", true);
assertThat(markableRef)
    .hasReference("value")
    .isMarked();

Concurrent Type Assertions

Assertions for concurrent programming constructs like futures and completion stages.

// Future assertions
FutureAssert<T> assertThat(Future<T> actual)
CompletableFutureAssert<T> assertThat(CompletableFuture<T> actual)
CompletionStageAssert<T> assertThat(CompletionStage<T> actual)

// Future state methods
FutureAssert<T> isDone()
FutureAssert<T> isNotDone()
FutureAssert<T> isCancelled()
FutureAssert<T> isNotCancelled()

// CompletableFuture methods
CompletableFutureAssert<T> isCompletedExceptionally()
CompletableFutureAssert<T> isNotCompletedExceptionally()
CompletableFutureAssert<T> isCompletedWithValue(T expected)
CompletableFutureAssert<T> isCompletedWithValueMatching(Predicate<T> predicate)
CompletableFutureAssert<T> hasFailed()
CompletableFutureAssert<T> hasNotFailed()
CompletableFutureAssert<T> hasFailedWithThrowableThat()

Usage examples:

// CompletableFuture assertions
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "result");
assertThat(future)
    .isDone()
    .isNotCancelled()
    .isCompletedWithValue("result");

// Exception handling in futures
CompletableFuture<String> failedFuture = CompletableFuture.failedFuture(
    new RuntimeException("Task failed")
);
assertThat(failedFuture)
    .isDone()
    .isCompletedExceptionally()
    .hasFailedWithThrowableThat()
    .isInstanceOf(RuntimeException.class)
    .hasMessage("Task failed");

// Async testing
CompletableFuture<Integer> asyncResult = CompletableFuture.supplyAsync(() -> {
    // Simulate work
    return 42;
});

assertThat(asyncResult)
    .succeedsWithin(Duration.ofSeconds(5))
    .isEqualTo(42);

Stream Assertions

Assertions for Java 8+ streams and stream operations.

// Stream assertions  
StreamAssert<T> assertThat(Stream<T> actual)
IntStreamAssert assertThat(IntStream actual)
LongStreamAssert assertThat(LongStream actual)
DoubleStreamAssert assertThat(DoubleStream actual)

// Stream content methods
StreamAssert<T> contains(T... values)
StreamAssert<T> containsExactly(T... values)
StreamAssert<T> containsOnly(T... values)
StreamAssert<T> doesNotContain(T... values)
StreamAssert<T> hasSize(int expected)
StreamAssert<T> isEmpty()
StreamAssert<T> isNotEmpty()

// Stream operations
StreamAssert<T> allMatch(Predicate<? super T> predicate)
StreamAssert<T> anyMatch(Predicate<? super T> predicate)  
StreamAssert<T> noneMatch(Predicate<? super T> predicate)

Usage examples:

// Stream content assertions
Stream<String> names = Stream.of("Alice", "Bob", "Charlie");
assertThat(names)
    .hasSize(3)
    .contains("Bob")
    .allMatch(name -> name.length() > 2);

// Numeric stream assertions
IntStream numbers = IntStream.range(1, 6); // 1,2,3,4,5
assertThat(numbers)
    .containsExactly(1, 2, 3, 4, 5)
    .allMatch(n -> n > 0)
    .noneMatch(n -> n > 10);

// Stream processing assertions
Stream<String> processed = Stream.of("apple", "banana", "cherry")
    .filter(s -> s.length() > 5)
    .map(String::toUpperCase);

assertThat(processed)
    .containsExactly("BANANA", "CHERRY");

Predicate Assertions

Assertions for functional predicates and their behavior.

// Predicate assertions
PredicateAssert<T> assertThat(Predicate<T> actual)
IntPredicateAssert assertThat(IntPredicate actual)
LongPredicateAssert assertThat(LongPredicate actual)
DoublePredicateAssert assertThat(DoublePredicate actual)

// Predicate behavior methods
PredicateAssert<T> accepts(T... values)
PredicateAssert<T> rejects(T... values)
PredicateAssert<T> acceptsAll(Iterable<T> values)
PredicateAssert<T> rejectsAll(Iterable<T> values)

Usage examples:

// Custom predicates
Predicate<String> isLongString = s -> s.length() > 5;
assertThat(isLongString)
    .accepts("Hello World", "Testing")
    .rejects("Hi", "Test");

Predicate<Integer> isEven = n -> n % 2 == 0;
assertThat(isEven)
    .accepts(2, 4, 6, 8)
    .rejects(1, 3, 5, 7);

// Numeric predicates
IntPredicate isPositive = n -> n > 0;
assertThat(isPositive)
    .accepts(1, 2, 100)
    .rejects(-1, 0, -100);

File System Assertions

Assertions for file and path operations.

// File assertions
FileAssert assertThat(File actual)
PathAssert assertThat(Path actual)
InputStreamAssert assertThat(InputStream actual)

// File existence and type
FileAssert exists()
FileAssert doesNotExist()
FileAssert isFile()
FileAssert isDirectory()
FileAssert isAbsolute()
FileAssert isRelative()
FileAssert isExecutable()
FileAssert isReadable()
FileAssert isWritable()

// File content
FileAssert hasContent(String expected)
FileAssert hasContentEqualTo(File expected)
FileAssert hasSameContentAs(File expected)
FileAssert hasSize(long expected)
FileAssert isEmpty()
FileAssert isNotEmpty()

// Path assertions
PathAssert exists()
PathAssert doesNotExist() 
PathAssert isAbsolute()
PathAssert isRelative()
PathAssert hasParent(Path expected)
PathAssert hasFileName(String expected)
PathAssert hasExtension(String expected)

Usage examples:

// File assertions
File configFile = new File("application.properties");
assertThat(configFile)
    .exists()
    .isFile()
    .isReadable()
    .hasContent("server.port=8080");

File dataDir = new File("data");
assertThat(dataDir)
    .exists()
    .isDirectory()
    .isWritable();

// Path assertions  
Path logFile = Paths.get("logs", "application.log");
assertThat(logFile)
    .hasFileName("application.log")
    .hasExtension("log")
    .hasParent(Paths.get("logs"));

// InputStream assertions
InputStream inputStream = new ByteArrayInputStream("test content".getBytes());
assertThat(inputStream)
    .hasContent("test content");

Network Assertions

Assertions for network-related types like URI and URL.

// URI assertions
UriAssert assertThat(URI actual)

// URI component methods
UriAssert hasScheme(String expected)
UriAssert hasHost(String expected)  
UriAssert hasPort(int expected)
UriAssert hasPath(String expected)
UriAssert hasQuery(String expected)
UriAssert hasFragment(String expected)
UriAssert hasAuthority(String expected)
UriAssert hasUserInfo(String expected)

// URL assertions
UrlAssert assertThat(URL actual)

// URL methods (similar to URI)
UrlAssert hasProtocol(String expected)
UrlAssert hasHost(String expected)
UrlAssert hasPort(int expected)
UrlAssert hasPath(String expected)
UrlAssert hasQuery(String expected)
UrlAssert hasAnchor(String expected)

Usage examples:

// URI assertions
URI apiUri = URI.create("https://api.example.com:8080/users?page=1#section");
assertThat(apiUri)
    .hasScheme("https")
    .hasHost("api.example.com")
    .hasPort(8080)
    .hasPath("/users")
    .hasQuery("page=1")
    .hasFragment("section");

// URL assertions
URL websiteUrl = new URL("http://www.example.com/page.html");
assertThat(websiteUrl)
    .hasProtocol("http")
    .hasHost("www.example.com")  
    .hasPath("/page.html");

Filtering and Extraction

Advanced filtering and value extraction from collections and arrays.

// Filtering collections and arrays
Filters<E> filter(E[] array)
Filters<E> filter(Iterable<E> iterable)

// Filter operations
Filters<E> with(String property, Object expectedValue)
Filters<E> with(String property)
Filters<E> with(Function<E, Object> propertyExtractor, Object expectedValue)
Filters<E> with(Condition<E> condition)
Filters<E> being(Condition<E> condition)

// Property extraction
ObjectArrayAssert<Object> extracting(String property)
ObjectArrayAssert<Tuple> extracting(String... properties)
ObjectArrayAssert<Object> extracting(Function<T, Object> extractor)
ObjectArrayAssert<Tuple> extracting(Function<T, Object>... extractors)

// Flat extraction (for nested collections)
ListAssert<Object> flatExtracting(String property)
ListAssert<Object> flatExtracting(Function<T, ?> extractor)

Usage examples:

// Complex filtering examples
List<Person> people = Arrays.asList(
    new Person("Alice", 30, "Engineer"),
    new Person("Bob", 25, "Designer"), 
    new Person("Charlie", 35, "Manager"),
    new Person("Diana", 28, "Engineer")
);

// Property-based filtering
assertThat(people)
    .filteredOn("profession", "Engineer")
    .extracting("name")
    .containsExactly("Alice", "Diana");

// Condition-based filtering
assertThat(people)
    .filteredOn(person -> person.getAge() > 28)
    .hasSize(2)
    .extracting("name")  
    .containsOnly("Alice", "Charlie");

// Multiple property extraction
assertThat(people)
    .extracting("name", "age", "profession")
    .contains(
        tuple("Alice", 30, "Engineer"),
        tuple("Bob", 25, "Designer")
    );

// Nested object extraction
List<Order> orders = getOrdersWithItems();
assertThat(orders)
    .flatExtracting(Order::getItems)
    .extracting(Item::getName)
    .contains("Product A", "Product B");

Groups and Tuples

Working with grouped data and tuple collections.

// Group creation
static <T> Group<T> group(String name, T... elements)
static <T> Group<T> group(T[] elements, String name)

// Tuple creation and operations
static Tuple tuple(Object... values)

// Tuple extraction
TupleAssert assertThat(Tuple actual)

// Tuple methods  
TupleAssert contains(Object... expectedValues)
TupleAssert containsExactly(Object... expectedValues)

Usage examples:

// Working with tuples
List<Person> people = getPeople();
assertThat(people)
    .extracting("firstName", "lastName", "age")
    .contains(
        tuple("John", "Doe", 30),
        tuple("Jane", "Smith", 25)
    );

// Custom tuple assertions
Tuple personTuple = tuple("Alice", 30, true);
assertThat(personTuple)
    .containsExactly("Alice", 30, true);

Recursive Comparison

Deep object comparison with customizable comparison strategies and comprehensive configuration options.

// Recursive comparison entry point
RecursiveComparisonAssert<?> usingRecursiveComparison()
RecursiveComparisonAssert<?> usingRecursiveComparison(RecursiveComparisonConfiguration configuration)

// Field filtering and selection
RecursiveComparisonAssert<?> ignoringFields(String... fields)
RecursiveComparisonAssert<?> ignoringFieldsOfTypes(Class<?>... types)
RecursiveComparisonAssert<?> ignoringFieldsMatchingRegexes(String... regexes)
RecursiveComparisonAssert<?> comparingOnlyFields(String... fields)
RecursiveComparisonAssert<?> comparingOnlyFieldsOfTypes(Class<?>... types)

// Null value handling  
RecursiveComparisonAssert<?> ignoringActualNullFields()
RecursiveComparisonAssert<?> ignoringExpectedNullFields()
RecursiveComparisonAssert<?> ignoringAllNullFields()

// Type checking and overriding
RecursiveComparisonAssert<?> withStrictTypeChecking()
RecursiveComparisonAssert<?> ignoringOverriddenEqualsForTypes(Class<?>... types)
RecursiveComparisonAssert<?> ignoringOverriddenEqualsForFields(String... fields)
RecursiveComparisonAssert<?> ignoringOverriddenEqualsForFieldsMatchingRegexes(String... regexes)

// Custom comparators
RecursiveComparisonAssert<?> withComparatorForType(Comparator<?> comparator, Class<?> type)
RecursiveComparisonAssert<?> withComparatorForFields(Comparator<?> comparator, String... fields)
RecursiveComparisonAssert<?> withComparatorForFieldsMatchingRegexes(Comparator<?> comparator, String... regexes)

// Collection element comparison
RecursiveComparisonAssert<?> ignoringCollectionOrder()
RecursiveComparisonAssert<?> ignoringCollectionOrderInFields(String... fields)
RecursiveComparisonAssert<?> ignoringCollectionOrderInFieldsMatchingRegexes(String... regexes)

// Configuration object
class RecursiveComparisonConfiguration {
    RecursiveComparisonConfiguration ignoreFields(String... fields)
    RecursiveComparisonConfiguration ignoreFieldsOfTypes(Class<?>... types)
    RecursiveComparisonConfiguration compareOnlyFields(String... fields)
    RecursiveComparisonConfiguration withComparatorForType(Comparator<?> comparator, Class<?> type)
    RecursiveComparisonConfiguration withStrictTypeChecking()
    RecursiveComparisonConfiguration ignoreCollectionOrder()
}

Usage examples:

// Basic recursive comparison
Person actualPerson = new Person("John", 30, 
    new Address("123 Main St", "Anytown", "12345"));
Person expectedPerson = new Person("John", 30, 
    new Address("123 Main St", "Anytown", "12345"));

assertThat(actualPerson)
    .usingRecursiveComparison()
    .isEqualTo(expectedPerson);

// Ignore specific fields across all levels
assertThat(actualPerson)
    .usingRecursiveComparison()
    .ignoringFields("id", "createdDate", "address.lastModified")
    .isEqualTo(expectedPerson);

// Ignore fields by type (e.g., all timestamps)
assertThat(actualPerson)
    .usingRecursiveComparison()
    .ignoringFieldsOfTypes(LocalDateTime.class, Timestamp.class)
    .isEqualTo(expectedPerson);

// Ignore fields matching patterns
assertThat(actualPerson)
    .usingRecursiveComparison()
    .ignoringFieldsMatchingRegexes(".*[Ii]d$", ".*[Dd]ate.*")
    .isEqualTo(expectedPerson);

// Compare only specific fields
assertThat(actualPerson)
    .usingRecursiveComparison()
    .comparingOnlyFields("name", "age", "address.street")
    .isEqualTo(expectedPerson);

// Custom comparators for specific types
assertThat(actualPerson)
    .usingRecursiveComparison()
    .withComparatorForType(String.CASE_INSENSITIVE_ORDER, String.class)
    .withComparatorForType(BigDecimal::compareTo, BigDecimal.class)
    .isEqualTo(expectedPerson);

// Custom comparators for specific fields
assertThat(actualPerson)
    .usingRecursiveComparison()
    .withComparatorForFields(String.CASE_INSENSITIVE_ORDER, "name", "address.city")
    .withComparatorForFieldsMatchingRegexes(Double::compareTo, ".*[Pp]rice.*")
    .isEqualTo(expectedPerson);

// Handle collections with different orders
List<Person> actualPeople = Arrays.asList(
    new Person("Alice", 30), new Person("Bob", 25)
);
List<Person> expectedPeople = Arrays.asList(
    new Person("Bob", 25), new Person("Alice", 30)
);

assertThat(actualPeople)
    .usingRecursiveComparison()
    .ignoringCollectionOrder()
    .isEqualTo(expectedPeople);

// Strict type checking (prevents comparing Integer with Long)
assertThat(actualValue)
    .usingRecursiveComparison()
    .withStrictTypeChecking()
    .isEqualTo(expectedValue);

// Ignore overridden equals methods for specific types
assertThat(actualPerson)
    .usingRecursiveComparison()
    .ignoringOverriddenEqualsForTypes(Address.class)
    .isEqualTo(expectedPerson);

// Pre-configured recursive comparison
RecursiveComparisonConfiguration config = new RecursiveComparisonConfiguration()
    .ignoreFields("id", "createdAt", "updatedAt")
    .ignoringFieldsOfTypes(UUID.class)
    .withComparatorForType(String.CASE_INSENSITIVE_ORDER, String.class)
    .ignoreCollectionOrder();

assertThat(actualObject)
    .usingRecursiveComparison(config)
    .isEqualTo(expectedObject);

// Complex nested object comparison
Order actualOrder = new Order(
    "ORD-001",
    Arrays.asList(
        new OrderItem("Product A", 2, new BigDecimal("29.99")),
        new OrderItem("Product B", 1, new BigDecimal("15.50"))
    ),
    new Customer("John Doe", "john@example.com")
);

Order expectedOrder = new Order(
    "ORD-001", 
    Arrays.asList(
        new OrderItem("Product B", 1, new BigDecimal("15.50")),
        new OrderItem("Product A", 2, new BigDecimal("29.99"))
    ),
    new Customer("john doe", "john@example.com")  // Different case
);

assertThat(actualOrder)
    .usingRecursiveComparison()
    .ignoringCollectionOrder()
    .withComparatorForFields(String.CASE_INSENSITIVE_ORDER, "customer.name")
    .isEqualTo(expectedOrder);

Framework Integration

Integration APIs for working with external frameworks and libraries.

// Mixin interface for assertion methods
interface WithAssertions {
    // Provides access to all static assertion methods
    // Implement this interface to get assertion methods without static imports
}

// Hamcrest integration
MatcherAssert.assertThat(T actual, Matcher<? super T> matcher)

// Usage in classes
class MyTestClass implements WithAssertions {
    @Test  
    void myTest() {
        // Can use assertThat without static import
        assertThat("Hello").startsWith("H");
    }
}

Usage examples:

// WithAssertions mixin - eliminates need for static imports
class IntegrationTest implements WithAssertions {
    
    @Test
    void testWithoutStaticImports() {
        // All AssertJ methods available directly
        assertThat("Hello World")
            .startsWith("Hello")
            .endsWith("World")
            .hasLength(11);
        
        assertThat(Arrays.asList(1, 2, 3))
            .hasSize(3)
            .contains(2)
            .doesNotContain(4);
        
        assertThatThrownBy(() -> {
            throw new IllegalStateException("Error");
        }).isInstanceOf(IllegalStateException.class);
    }
    
    @Test
    void testComplexAssertions() {
        List<Person> people = getPeople();
        
        assertThat(people)
            .filteredOn(person -> person.getAge() > 18)
            .extracting("name") 
            .containsOnly("Alice", "Bob", "Charlie");
    }
}

// Hamcrest integration - use Hamcrest matchers with AssertJ
import static org.hamcrest.Matchers.*;
import static org.assertj.core.api.MatcherAssert.assertThat;

@Test  
void testWithHamcrestMatchers() {
    String text = "Hello World";
    
    // Use Hamcrest matchers with AssertJ's MatcherAssert
    assertThat(text, startsWith("Hello"));
    assertThat(text, endsWith("World"));
    assertThat(text, containsString("lo Wo"));
    
    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    assertThat(numbers, hasSize(5));
    assertThat(numbers, hasItem(3));
    assertThat(numbers, everyItem(greaterThan(0)));
}

// Custom matchers with Hamcrest
public static Matcher<Person> hasAge(int expectedAge) {
    return new BaseMatcher<Person>() {
        @Override
        public boolean matches(Object item) {
            return item instanceof Person && ((Person) item).getAge() == expectedAge;
        }
        
        @Override
        public void describeTo(Description description) {
            description.appendText("person with age ").appendValue(expectedAge);
        }
    };
}

@Test
void testWithCustomMatcher() {
    Person person = new Person("Alice", 30);
    assertThat(person, hasAge(30));
}

// Combining AssertJ and Hamcrest
@Test
void testCombinedApproaches() {
    List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
    
    // Use AssertJ for fluent assertions
    org.assertj.core.api.Assertions.assertThat(names)
        .hasSize(3)
        .allMatch(name -> name.length() > 2);
    
    // Use Hamcrest for pattern matching
    assertThat(names, hasItems("Alice", "Bob"));
    assertThat(names, everyItem(not(isEmptyString())));
}

Extension Points

Extension interfaces and factories for customizing AssertJ behavior and error handling.

// Error factories for custom assertion error creation
interface AssertionErrorFactory {
    AssertionError newAssertionError(Description description, Representation representation)
}

interface ErrorMessageFactory {
    String create(Description description, Representation representation)
}

// Comparison strategy interface for custom comparison logic
interface ComparisonStrategy {
    boolean areEqual(Object actual, Object other)
    String asText()
}

// Representation interface for custom object formatting
interface Representation {
    String toStringOf(Object object)
    String unambiguousToStringOf(Object object)
}

// Description builder for assertion messages
interface Description {
    Description appendText(String text)
    Description appendDescriptionOf(SelfDescribing value)
    Description appendValue(Object value)
    Description appendValueList(String start, String separator, String end, Object... values)
}

// Configuration factories
static AssertionErrorFactory setAssertionErrorFactory(AssertionErrorFactory factory)
static ComparisonStrategy setComparisonStrategy(ComparisonStrategy comparisonStrategy)

Usage examples:

// Custom assertion error factory
public class CustomAssertionErrorFactory implements AssertionErrorFactory {
    @Override
    public AssertionError newAssertionError(Description description, 
                                          Representation representation) {
        String message = description.toString();
        // Add custom formatting, logging, or context
        Logger.getLogger("test").error("Assertion failed: " + message);
        return new AssertionError("[CUSTOM] " + message);
    }
}

// Register custom error factory globally
Assertions.setAssertionErrorFactory(new CustomAssertionErrorFactory());

@Test
void testWithCustomErrorFactory() {
    // Failures now use custom error factory
    assertThat("Hello").isEqualTo("World"); // Custom formatted error
}

// Custom comparison strategy for case-insensitive strings
public class CaseInsensitiveComparisonStrategy implements ComparisonStrategy {
    @Override
    public boolean areEqual(Object actual, Object other) {
        if (actual instanceof String && other instanceof String) {
            return ((String) actual).equalsIgnoreCase((String) other);
        }
        return Objects.equals(actual, other);
    }
    
    @Override
    public String asText() {
        return "CaseInsensitiveComparisonStrategy";
    }
}

// Use custom comparison strategy
ComparisonStrategy originalStrategy = Assertions.getComparisionStrategy();
try {
    Assertions.setComparisonStrategy(new CaseInsensitiveComparisonStrategy());
    
    assertThat("Hello").isEqualTo("HELLO"); // Passes with case-insensitive comparison
    assertThat(Arrays.asList("Test", "DATA"))
        .contains("test", "data"); // Case-insensitive collection comparison
        
} finally {
    // Restore original strategy
    Assertions.setComparisonStrategy(originalStrategy);
}

// Custom representation for domain objects
public class PersonRepresentation extends StandardRepresentation {
    @Override
    public String toStringOf(Object object) {
        if (object instanceof Person) {
            Person p = (Person) object;
            return String.format("Person{name='%s', age=%d, email='%s'}", 
                               p.getName(), p.getAge(), p.getEmail());
        }
        return super.toStringOf(object);
    }
}

// Use custom representation
Representation originalRep = Assertions.getRepresentation();
try {
    Assertions.useRepresentation(new PersonRepresentation());
    
    Person person = new Person("Alice", 30, "alice@example.com");
    assertThat(person).isNull(); // Error message uses custom representation
    
} finally {
    Assertions.useRepresentation(originalRep);
}

// Custom error message factory
public class CustomErrorMessageFactory implements ErrorMessageFactory {
    @Override
    public String create(Description description, Representation representation) {
        String baseMessage = description.toString();
        
        // Add contextual information
        Thread currentThread = Thread.currentThread();
        String threadInfo = String.format(" [Thread: %s, Time: %s]", 
                                        currentThread.getName(), 
                                        Instant.now());
        
        return baseMessage + threadInfo;
    }
}

// Custom description builder for complex assertions
public class DetailedDescription implements Description {
    private final StringBuilder sb = new StringBuilder();
    
    @Override
    public Description appendText(String text) {
        sb.append(text);
        return this;
    }
    
    @Override
    public Description appendDescriptionOf(SelfDescribing value) {
        sb.append(value.toString());
        return this;
    }
    
    @Override
    public Description appendValue(Object value) {
        sb.append("'").append(value).append("'");
        return this;
    }
    
    @Override
    public Description appendValueList(String start, String separator, 
                                     String end, Object... values) {
        sb.append(start);
        for (int i = 0; i < values.length; i++) {
            if (i > 0) sb.append(separator);
            appendValue(values[i]);
        }
        sb.append(end);
        return this;
    }
    
    @Override
    public String toString() {
        return sb.toString();
    }
}

// Extension point for custom assert classes
public class CustomStringAssert extends AbstractStringAssert<CustomStringAssert> {
    
    public CustomStringAssert(String actual) {
        super(actual, CustomStringAssert.class);
    }
    
    public static CustomStringAssert assertThat(String actual) {
        return new CustomStringAssert(actual);
    }
    
    // Custom assertion method
    public CustomStringAssert isValidEmail() {
        isNotNull();
        if (!actual.contains("@") || !actual.contains(".")) {
            failWithMessage("Expected <%s> to be a valid email address", actual);
        }
        return this;
    }
    
    // Custom assertion with detailed error
    public CustomStringAssert hasValidLength(int min, int max) {
        isNotNull();
        int length = actual.length();
        if (length < min || length > max) {
            failWithMessage("Expected string length to be between <%d> and <%d> but was <%d>",
                          min, max, length);
        }
        return this;
    }
}

// Usage of custom assert class
@Test
void testWithCustomStringAssert() {
    CustomStringAssert.assertThat("user@example.com")
        .isValidEmail()
        .hasValidLength(5, 50)
        .startsWith("user");
        
    CustomStringAssert.assertThat("invalid-email")
        .isValidEmail(); // Fails with custom message
}

// Global extension configuration
@BeforeAll
static void configureAssertJ() {
    // Set custom factories and strategies globally
    Assertions.setAssertionErrorFactory(new CustomAssertionErrorFactory());
    Assertions.useRepresentation(new PersonRepresentation());
    
    // Configure behavior
    Assertions.setAllowExtractingPrivateFields(true);
    Assertions.setMaxElementsForPrinting(100);
    Assertions.setPrintAssertionsDescription(true);
}

Configuration and Utilities

Global configuration and utility methods.

// Global configuration methods
static void setAllowExtractingPrivateFields(boolean allowExtractingPrivateFields)
static void setAllowComparingPrivateFields(boolean allowComparingPrivateFields)
static void setExtractBareNamePropertyMethods(boolean extractBareNamePropertyMethods)
static void setLenientDateParsing(boolean lenientDateParsing)
static void setMaxElementsForPrinting(int maxElementsForPrinting)
static void setMaxLengthForSingleLineDescription(int maxLengthForSingleLineDescription)
static void setPrintAssertionsDescription(boolean printAssertionsDescription)

// Representation configuration
static void useDefaultRepresentation()
static void useRepresentation(Representation representation)

// Date parsing configuration
static void useDefaultDateFormatsOnly()
static void registerCustomDateFormat(DateFormat customDateFormat)
static void registerCustomDateFormat(String customDateFormatPattern)

Usage examples:

// Configure AssertJ behavior globally
Assertions.setMaxElementsForPrinting(50);
Assertions.setPrintAssertionsDescription(true);
Assertions.setLenientDateParsing(true);

// Custom representation
Assertions.useRepresentation(new StandardRepresentation() {
    @Override
    protected String toStringOf(Object object) {
        if (object instanceof Person) {
            Person p = (Person) object;
            return String.format("Person[%s, %d]", p.getName(), p.getAge());
        }
        return super.toStringOf(object);
    }
});

Types

// Atomic reference types
class AtomicReference<V> {
    V get()
    void set(V newValue)
    boolean compareAndSet(V expect, V update)
}

class AtomicInteger extends Number {
    int get()
    void set(int newValue)
    int addAndGet(int delta)
    boolean compareAndSet(int expect, int update)
}

// Concurrent types
interface Future<V> {
    boolean isDone()
    boolean isCancelled()
    V get() throws InterruptedException, ExecutionException
}

class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
    boolean isCompletedExceptionally()
    T join()
    static <U> CompletableFuture<U> completedFuture(U value)
    static <U> CompletableFuture<U> failedFuture(Throwable ex)
}

// Stream types
interface Stream<T> extends BaseStream<T, Stream<T>> {
    Stream<T> filter(Predicate<? super T> predicate)
    <R> Stream<R> map(Function<? super T, ? extends R> mapper)
    boolean allMatch(Predicate<? super T> predicate)
    boolean anyMatch(Predicate<? super T> predicate)
    boolean noneMatch(Predicate<? super T> predicate)
}

// File system types
class File {
    boolean exists()
    boolean isFile()
    boolean isDirectory()
    long length()
    boolean canRead()
    boolean canWrite()
    boolean canExecute()
}

interface Path {
    boolean isAbsolute()
    Path getParent()
    Path getFileName()
    String toString()
}

// Filter and extraction types
class Filters<E> {
    Filters<E> with(String property, Object expectedValue)
    Filters<E> with(Condition<E> condition)
}

class Tuple {
    static Tuple tuple(Object... values)
    Object[] toArray()
    List<Object> toList()
}

// Functional interfaces
interface Predicate<T> {
    boolean test(T t);
}

interface Function<T, R> {
    R apply(T t);
}

interface Consumer<T> {
    void accept(T t);
}

// Comparison types
interface Comparator<T> {
    int compare(T o1, T o2);
}

class RecursiveComparisonConfiguration {
    RecursiveComparisonConfiguration ignoreFields(String... fields)
    RecursiveComparisonConfiguration ignoreFieldsOfTypes(Class<?>... types)
    RecursiveComparisonConfiguration ignoreFieldsMatchingRegexes(String... regexes)
    RecursiveComparisonConfiguration compareOnlyFields(String... fields)
    RecursiveComparisonConfiguration compareOnlyFieldsOfTypes(Class<?>... types)
    RecursiveComparisonConfiguration ignoringActualNullFields()
    RecursiveComparisonConfiguration ignoringExpectedNullFields()
    RecursiveComparisonConfiguration ignoringAllNullFields()
    RecursiveComparisonConfiguration withStrictTypeChecking()
    RecursiveComparisonConfiguration ignoringOverriddenEqualsForTypes(Class<?>... types)
    RecursiveComparisonConfiguration ignoringOverriddenEqualsForFields(String... fields)
    RecursiveComparisonConfiguration withComparatorForType(Comparator<?> comparator, Class<?> type)
    RecursiveComparisonConfiguration withComparatorForFields(Comparator<?> comparator, String... fields)
    RecursiveComparisonConfiguration ignoreCollectionOrder()
    RecursiveComparisonConfiguration ignoringCollectionOrderInFields(String... fields)
}

// Extension interfaces
interface AssertionErrorFactory {
    AssertionError newAssertionError(Description description, Representation representation)
}

interface ErrorMessageFactory {
    String create(Description description, Representation representation)
}

interface ComparisonStrategy {
    boolean areEqual(Object actual, Object other)
    String asText()
}

interface Representation {
    String toStringOf(Object object)
    String unambiguousToStringOf(Object object)
}

interface Description {
    Description appendText(String text)
    Description appendDescriptionOf(SelfDescribing value)  
    Description appendValue(Object value)
    Description appendValueList(String start, String separator, String end, Object... values)
}

// Assumption types
interface Assumptions {
    static <T> ObjectAssert<T> assumeThat(T actual)
    static BooleanAssert assumeThat(boolean actual)
    static StringAssert assumeThat(String actual) 
    static IntegerAssert assumeThat(int actual)
    static <T> ListAssert<T> assumeThat(List<T> actual)
    static void assumingThat(boolean assumption, ThrowingCallable executable)
    static void assumingThat(boolean assumption, Runnable executable)
}

// Integration types  
interface WithAssertions {
    // Mixin interface providing access to all assertion methods
    // Classes implementing this can use assertThat methods without static imports
}

class MatcherAssert {
    static <T> void assertThat(T actual, Matcher<? super T> matcher)
}

Install with Tessl CLI

npx tessl i tessl/maven-org-assertj--assertj-core

docs

advanced.md

basic-assertions.md

collections.md

conditions.md

dates-times.md

exceptions.md

index.md

soft-assertions.md

strings.md

tile.json