A Detailed Guide to AssertJ Assertions

AssertJ is a widely adopted Java assertion library, often used alongside testing frameworks such as JUnit and TestNG. Its main goal is to make test code easier to read while giving developers richer failure details when something goes wrong.

  • Fluent API: Assertions are written as readable chains instead of separate checks.
  • Broad coverage: Common types such as objects, strings, collections, numbers, dates, and exceptions can be tested.
  • Better failures: When a check fails, AssertJ can show actual and expected values in a clearer way.
  • Advanced features: Soft assertions and custom assertions help with more complex scenarios.

In a Maven project, the core dependency looks like this:

<dependency>
    <groupId>org.assertj</groupId>
    <artifactId>assertj-core</artifactId>
    <version>3.25.3</version>
    <scope>test</scope>
</dependency>

If the project already uses spring-boot-starter-test, AssertJ is usually included automatically, so no extra dependency is needed.

The Fluent Entry Point

The central starting point is the static method Assertions.assertThat(). From there, assertions are chained for the same object.

import static org.assertj.core.api.Assertions.assertThat;

assertThat("Hello AssertJ")
        .isNotEmpty()
        .startsWith("Hello")
        .contains("AssertJ")
        .hasSize(13);

Each method in the chain applies to the same subject. If one assertion fails, an AssertionError is thrown, often with useful context about the mismatch.

Object Assertions

Object assertions are useful for checking nulls, types, field values, and object equality.

User user = new User("Alice", 25);

assertThat(user)
        .isNotNull()
        .isInstanceOf(User.class)
        .hasFieldOrPropertyWithValue("name", "Alice");

assertThat(user).usingRecursiveComparison()
        .isEqualTo(new User("Alice", 25));

Common methods include isEqualTo, isNull, and isSameAs. The usingRecursiveComparison() method is helpful when you need to compare objects field by field without relying on equals.

String Assertions

String assertions cover blank text, prefixes, suffixes, content, and patterns.

String text = "AssertJ Tutorial";

assertThat(text)
        .isNotBlank()
        .startsWith("AssertJ")
        .endsWith("Tutorial")
        .contains(" ")
        .matches("[A-Za-z ]+");

These checks are especially useful for validating user input, messages, and formatted output.

Collection Assertions

Collections are one of the strongest areas of AssertJ. Beyond basic inclusion and size checks, it supports filtering and field extraction.

List<String> languages = List.of("Java", "Kotlin", "Scala");

assertThat(languages)
        .hasSize(3)
        .contains("Java", "Kotlin")
        .doesNotContain("Python")
        .isSorted();

List<User> users = List.of(
        new User("Alice", 30),
        new User("Bob", 17)
);

assertThat(users)
        .filteredOn(user -> user.getAge() > 18)
        .extracting(User::getName)
        .containsExactlyInAnyOrder("Alice");

The ability to filter and extract makes collection tests more expressive and less verbose.

Numeric Assertions

Numeric assertions help verify values, ranges, and floating-point closeness.

double result = 10.0 / 3.0;

assertThat(result)
        .isPositive()
        .isBetween(3.0, 3.5)
        .isCloseTo(3.33, within(0.01));

Using isCloseTo with within is a recommended approach when comparing floating-point numbers, because exact equality can be fragile.

Exception Assertions

AssertJ provides dedicated assertions for exception behavior.

assertThatThrownBy(() -> {
        throw new IllegalArgumentException("Invalid parameter");
})
        .isInstanceOf(IllegalArgumentException.class)
        .hasMessage("Invalid parameter")
        .hasMessageContaining("Invalid");

If the code should not throw an exception, use assertThatCode(...).doesNotThrowAnyException().

Soft Assertions

By default, an assertion failure stops the test immediately. Soft assertions allow a test to collect multiple failures before reporting them together.

SoftAssertions softly = new SoftAssertions();

softly.assertThat(user.getName()).isEqualTo("Alice");
softly.assertThat(user.getAge()).isGreaterThan(18);

softly.assertAll();

The assertAll() method must be called to make the collected assertions effective.

AssertJ Versus JUnit Assertions

Feature JUnit AssertJ
Style Parameterized Fluent and chained
Readability Basic Strong
Failure details Simple Detailed and clear
Collection support Limited Rich

For example, JUnit may use assertTrue(list.contains("Java")), while AssertJ uses assertThat(list).contains("Java"). The latter gives more meaningful feedback when the expectation is not met.

Final Thoughts

AssertJ improves test readability through fluent method names and chains. It also provides detailed failure information and supports advanced patterns such as soft assertions and recursive comparison.

For many Java projects, using assertThat as the standard assertion entry point is a practical choice. Developers can then take advantage of collection filtering, field extraction, and richer exception checks while keeping tests clear and maintainable.