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

soft-assertions.mddocs/

Soft Assertions

Soft assertions collect multiple assertion failures and report them together instead of failing on the first error, enabling comprehensive validation in a single test.

Core Imports

import static org.assertj.core.api.Assertions.*;
import org.assertj.core.api.SoftAssertions;
import org.assertj.core.api.AutoCloseableSoftAssertions;
import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension;
import org.junit.jupiter.api.extension.ExtendWith;

Capabilities

Basic Soft Assertions

Standard soft assertions that collect errors and report them all at once.

class SoftAssertions {
    // Constructor
    SoftAssertions()
    
    // All standard assertThat methods available
    BooleanAssert assertThat(boolean actual)
    IntegerAssert assertThat(int actual)
    StringAssert assertThat(String actual)
    ObjectAssert<T> assertThat(T actual)
    ListAssert<T> assertThat(List<T> actual)
    // ... all other assertThat overloads
    
    // Soft assertion control
    void assertAll()
    List<AssertionError> assertionErrorsCollected()
    boolean hasErrors()
    boolean wasSuccess()
    
    // Error message customization
    SoftAssertions describedAs(String description)
    SoftAssertions as(String description)
}

Usage examples:

// Basic soft assertions usage
SoftAssertions softly = new SoftAssertions();

User user = getUser();
softly.assertThat(user.getName()).isNotNull();
softly.assertThat(user.getAge()).isPositive();
softly.assertThat(user.getEmail()).contains("@");
softly.assertThat(user.getRole()).isEqualTo(Role.ADMIN);

// This will throw AssertionError with ALL failures
softly.assertAll();

// Check if there were any errors without throwing
if (softly.hasErrors()) {
    List<AssertionError> errors = softly.assertionErrorsCollected();
    // Handle errors as needed
}

Auto-Closeable Soft Assertions

Soft assertions that automatically call assertAll() when used in try-with-resources.

class AutoCloseableSoftAssertions extends SoftAssertions implements AutoCloseable {
    // Constructor
    AutoCloseableSoftAssertions()
    
    // AutoCloseable implementation
    void close()
    
    // Inherits all SoftAssertions methods
    // Automatically calls assertAll() on close
}

Usage examples:

// Try-with-resources automatically calls assertAll()
try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) {
    softly.assertThat(name).isNotBlank();
    softly.assertThat(age).isBetween(18, 65);
    softly.assertThat(email).matches("\\w+@\\w+\\.\\w+");
    // assertAll() called automatically when exiting try block
}

// Validation method using auto-closeable soft assertions
public void validatePerson(Person person) {
    try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) {
        softly.assertThat(person).isNotNull();
        softly.assertThat(person.getName()).isNotEmpty();
        softly.assertThat(person.getAge()).isGreaterThan(0);
    } // assertAll() called here
}

BDD Style Soft Assertions

Behavior-driven development style soft assertions using then() instead of assertThat().

class BDDSoftAssertions {
    // Constructor
    BDDSoftAssertions()
    
    // BDD-style assertion methods (then instead of assertThat)
    BooleanAssert then(boolean actual)
    IntegerAssert then(int actual)
    StringAssert then(String actual)
    ObjectAssert<T> then(T actual)
    ListAssert<T> then(List<T> actual)
    // ... all other then() overloads
    
    // Control methods
    void assertAll()
    List<AssertionError> assertionErrorsCollected()
}

class AutoCloseableBDDSoftAssertions extends BDDSoftAssertions implements AutoCloseable {
    // Constructor
    AutoCloseableBDDSoftAssertions()
    
    // AutoCloseable implementation
    void close()
}

Usage examples:

// BDD-style soft assertions
BDDSoftAssertions softly = new BDDSoftAssertions();

// Given
Order order = createTestOrder();

// When  
ProcessResult result = orderProcessor.process(order);

// Then
softly.then(result.isSuccess()).isTrue();
softly.then(result.getOrderId()).isNotNull();
softly.then(result.getTotal()).isGreaterThan(BigDecimal.ZERO);
softly.assertAll();

// Auto-closeable BDD style
try (AutoCloseableBDDSoftAssertions softly = new AutoCloseableBDDSoftAssertions()) {
    softly.then(order.getItems()).isNotEmpty();
    softly.then(order.getCustomer()).isNotNull();
    softly.then(order.getStatus()).isEqualTo(OrderStatus.PENDING);
}

JUnit 4 Integration

Soft assertions integrated with JUnit 4 using rules.

class JUnitSoftAssertions extends SoftAssertions {
    // JUnit 4 Rule support
    static JUnitSoftAssertions assertSoftly()
}

class JUnitBDDSoftAssertions extends BDDSoftAssertions {
    // JUnit 4 BDD Rule support  
    static JUnitBDDSoftAssertions assertSoftly()
}

Usage examples:

// JUnit 4 with Rule (not commonly used in modern code)
public class MyTest {
    @Rule
    public final JUnitSoftAssertions softly = new JUnitSoftAssertions();
    
    @Test
    public void testValidation() {
        softly.assertThat(value1).isPositive();
        softly.assertThat(value2).isNotNull();
        // assertAll() called automatically by rule
    }
}

JUnit 5 Integration

Modern JUnit 5 integration with extensions and parameter injection.

class JUnitJupiterSoftAssertions extends SoftAssertions {
    // Constructor
    JUnitJupiterSoftAssertions()
}

class JUnitJupiterBDDSoftAssertions extends BDDSoftAssertions {
    // Constructor  
    JUnitJupiterBDDSoftAssertions()
}

// Extension for automatic injection
class SoftAssertionsExtension implements ParameterResolver {
    // Provides SoftAssertions instances to test methods
}

Usage examples:

// Method 1: Extension with parameter injection
@ExtendWith(SoftAssertionsExtension.class)
class ValidationTest {
    
    @Test
    void shouldValidateUser(SoftAssertions softly) {
        User user = createTestUser();
        
        softly.assertThat(user.getName()).isNotBlank();
        softly.assertThat(user.getEmail()).contains("@");
        softly.assertThat(user.isActive()).isTrue();
        
        softly.assertAll();
    }
}

// Method 2: Manual instantiation  
class UserTest {
    
    @Test
    void shouldValidateUserManually() {
        JUnitJupiterSoftAssertions softly = new JUnitJupiterSoftAssertions();
        
        User user = createTestUser();
        softly.assertThat(user.getName()).startsWith("Test");
        softly.assertThat(user.getCreatedDate()).isBeforeOrEqualTo(LocalDate.now());
        
        softly.assertAll();
    }
}

Error Collection and Reporting

Advanced error handling and custom reporting.

// Error collection methods
List<AssertionError> assertionErrorsCollected()
boolean hasErrors() 
boolean wasSuccess()
String errorsAsString()

// Custom error handling
SoftAssertions onError(Consumer<AssertionError> errorHandler)
SoftAssertions collectErrors(boolean collect)

Usage examples:

SoftAssertions softly = new SoftAssertions();

// Collect multiple validation errors
softly.assertThat(user.getName()).isNotNull();
softly.assertThat(user.getAge()).isBetween(0, 120);
softly.assertThat(user.getEmail()).matches(".*@.*\\..*");

// Check for errors without throwing
if (softly.hasErrors()) {
    List<AssertionError> errors = softly.assertionErrorsCollected();
    
    // Log each error individually  
    errors.forEach(error -> logger.error("Validation failed: {}", error.getMessage()));
    
    // Or get all errors as string
    String allErrors = softly.errorsAsString();
    throw new ValidationException("Multiple validation errors: " + allErrors);
}

Custom Soft Assertion Extensions

Creating custom soft assertions for domain objects.

// Extending SoftAssertions for custom types
class CustomSoftAssertions extends SoftAssertions {
    
    public UserAssert assertThat(User actual) {
        return proxy(UserAssert.class, User.class, actual);
    }
    
    public OrderAssert assertThat(Order actual) {
        return proxy(OrderAssert.class, Order.class, actual);
    }
}

Usage examples:

// Custom domain-specific soft assertions
class UserSoftAssertions extends SoftAssertions {
    
    public UserAssert assertThat(User actual) {
        return proxy(UserAssert.class, User.class, actual);
    }
}

class UserAssert extends AbstractObjectAssert<UserAssert, User> {
    
    public UserAssert(User actual) {
        super(actual, UserAssert.class);
    }
    
    public UserAssert hasValidEmail() {
        isNotNull();
        if (!actual.getEmail().contains("@")) {
            failWithMessage("Expected email to contain @ but was <%s>", actual.getEmail());
        }
        return this;
    }
    
    public UserAssert isAdult() {
        isNotNull();
        if (actual.getAge() < 18) {
            failWithMessage("Expected user to be adult but age was <%d>", actual.getAge());
        }
        return this;
    }
}

// Usage
UserSoftAssertions softly = new UserSoftAssertions();
softly.assertThat(user1).hasValidEmail().isAdult();
softly.assertThat(user2).hasValidEmail().isAdult();
softly.assertAll();

Soft Assertion Best Practices

Common patterns and best practices for soft assertions.

// Validation helper methods
static void validateUser(User user) {
    try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) {
        softly.assertThat(user).isNotNull();
        softly.assertThat(user.getName()).isNotBlank();
        softly.assertThat(user.getAge()).isPositive();
        softly.assertThat(user.getEmail()).contains("@");
    }
}

// Batch validation
static void validateUsers(List<User> users) {
    try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) {
        softly.assertThat(users).isNotEmpty();
        
        for (int i = 0; i < users.size(); i++) {
            User user = users.get(i);
            softly.assertThat(user.getName())
                  .as("User[%d] name", i)
                  .isNotBlank();
            softly.assertThat(user.getEmail())
                  .as("User[%d] email", i)  
                  .contains("@");
        }
    }
}

Types

// Core soft assertion classes
abstract class AbstractSoftAssertions {
    protected List<AssertionError> errors
    protected boolean collectErrors
    
    void assertAll()
    List<AssertionError> assertionErrorsCollected()
}

class SoftAssertions extends AbstractSoftAssertions {
    // Standard soft assertions implementation
}

class AutoCloseableSoftAssertions extends SoftAssertions implements AutoCloseable {
    void close() // calls assertAll()
}

// BDD variants
class BDDSoftAssertions extends AbstractSoftAssertions {
    // BDD-style methods using then() instead of assertThat()
}

class AutoCloseableBDDSoftAssertions extends BDDSoftAssertions implements AutoCloseable {
    void close()
}

// JUnit integration classes
class JUnitSoftAssertions extends SoftAssertions {
    // JUnit 4 integration
}

class JUnitJupiterSoftAssertions extends SoftAssertions {
    // JUnit 5 integration  
}

// Error handling
class AssertionError extends Error {
    String getMessage()
    Throwable getCause()
}

// Consumer for error handling
interface Consumer<T> {
    void accept(T t);
}

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