Close

AssertJ - Common Mistakes to Avoid

[Last Updated: Mar 3, 2026]

AssertJ's fluent API is intuitive, but a few patterns look correct while actually performing no assertion at all. These silent mistakes let broken code pass tests undetected. Understanding them prevents subtle bugs in your test suite.

Mistake 1: Passing an expression to assertThat()

Wrapping a boolean expression in assertThat() without chaining an assertion does nothing — the expression is evaluated but never checked:

// WRONG: no assertion, always passes
assertThat(actual.equals(expected));

// CORRECT:
assertThat(actual).isEqualTo(expected);

Mistake 2: Calling as() After the Assertion

If the assertion fails before reaching as(), the description is never applied. Always call as() before the assertion:

// WRONG
assertThat(actual).isEqualTo(expected).as("label");
// CORRECT
assertThat(actual).as("label").isEqualTo(expected);

Mistake 3: Setting withFailMessage/overridingErrorMessage After the Assertion

The same ordering rule applies to custom error messages:

// WRONG
assertThat(actual).isEqualTo(expected).withFailMessage("msg");
// CORRECT
assertThat(actual).withFailMessage("msg").isEqualTo(expected);

Detecting Mistakes with Static Analysis

Tools like SpotBugs (with the RV_RETURN_VALUE_IGNORED_INFERRED rule) and SonarQube (rule S2970) can detect incomplete AssertJ assertion chains at compile time. Enabling these saves the team from discovering the issue in production.

Example

package com.logicbig.example;

import org.junit.jupiter.api.Test;

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

public class CorrectUsageExample {

    @Test
    void myTest() {
        String actual = "hello";
        String expected = "hello";

        // CORRECT: assertThat(actual) then assertion method
        assertThat(actual).isEqualTo(expected);
        System.out.println("Correct equality check passed");

        // CORRECT: as() before assertion
        assertThat(actual).as("string value check").isEqualTo(expected);
        System.out.println("Correct as() usage passed");

        // CORRECT: withFailMessage before assertion
        assertThat(42).withFailMessage("should be 42").isEqualTo(42);
        System.out.println("Correct withFailMessage passed");

        // CORRECT: usingComparator before assertion
        assertThat(actual).usingComparator(String.CASE_INSENSITIVE_ORDER)
                          .isEqualTo("HELLO");
        System.out.println("Correct comparator usage passed");
    }
}

Output

$ mvn clean test -Dtest=*
[INFO] Scanning for projects...
[INFO]
[INFO] ------------< com.logicbig.example:assertj-common-mistakes >------------
[INFO] Building assertj-common-mistakes 1.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- clean:3.2.0:clean (default-clean) @ assertj-common-mistakes ---
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ assertj-common-mistakes ---
[INFO] skip non existing resourceDirectory D:\example-projects\assertj\assertj-common-mistakes\src\main\resources
[INFO]
[INFO] --- compiler:3.11.0:compile (default-compile) @ assertj-common-mistakes ---
[INFO] No sources to compile
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ assertj-common-mistakes ---
[INFO] skip non existing resourceDirectory D:\example-projects\assertj\assertj-common-mistakes\src\test\resources
[INFO]
[INFO] --- compiler:3.11.0:testCompile (default-testCompile) @ assertj-common-mistakes ---
[INFO] Changes detected - recompiling the module! :source
[INFO] Compiling 1 source file with javac [debug target 17] to target\test-classes
[INFO]
[INFO] --- surefire:3.2.5:test (default-test) @ assertj-common-mistakes ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[WARNING] file.encoding cannot be set as system property, use <argLine>-Dfile.encoding=...</argLine> instead
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.logicbig.example.CorrectUsageExample
Correct equality check passed
Correct as() usage passed
Correct withFailMessage passed
Correct comparator usage passed
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.093 s -- in com.logicbig.example.CorrectUsageExample
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.308 s
[INFO] Finished at: 2026-03-03T14:24:38+08:00
[INFO] ------------------------------------------------------------------------

Conclusion

The example uses correct assertion ordering throughout. By placing as() and withFailMessage() before the terminal assertion method, all descriptions and custom messages are guaranteed to apply. The output confirms every assertion passes, validating the correct usage patterns.

Example Project

Dependencies and Technologies Used:

  • assertj-core 3.27.7 (Rich and fluent assertions for testing in Java)
  • junit-jupiter-engine 6.0.2 (Module "junit-jupiter-engine" of JUnit)
  • JDK 17
  • Maven 3.9.11

AssertJ - Avoiding Common Mistakes Select All Download
  • assertj-common-mistakes
    • src
      • test
        • java
          • com
            • logicbig
              • example
                • CorrectUsageExample.java

    See Also

    Join