Close

AssertJ - Custom Error Messages

[Last Updated: Mar 3, 2026]

AssertJ generates informative error messages by default, but sometimes a domain-specific message is more useful to the person reading a CI failure log. The methods withFailMessage() and overridingErrorMessage() replace the default AssertJ message entirely with your own text.

withFailMessage vs overridingErrorMessage

Both methods are functionally identical — withFailMessage was added as a more readable alias. Use either to supply a static message string or, for expensive-to-build messages, a Supplier<String> so the message is only constructed on failure.

Important: Must Come Before the Assertion

Like as(), these methods must be called before the assertion itself. Placing them after the assertion has no effect because a failing assertion throws immediately.

// CORRECT
assertThat(value).withFailMessage("Expected active user").isTrue();

// WRONG - message ignored
assertThat(value).isTrue().withFailMessage("Expected active user");

Lazy Message (Supplier)

When the message construction is costly (e.g., involves I/O or reflection), use the Supplier<String> variant to defer evaluation:

assertThat(result).withFailMessage(() -> "Computed: " + buildReport()).isNotNull();

Example

package com.logicbig.example;

import org.junit.jupiter.api.Test;

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

public class CustomErrorMessageExample {

    @Test
    void myTest() {
        String status = "ACTIVE";

        // withFailMessage before assertion
        assertThat(status).withFailMessage("User status must be ACTIVE")
                          .isEqualTo("ACTIVE");
        System.out.println("withFailMessage passed");

        // overridingErrorMessage (alias)
        assertThat(42).overridingErrorMessage("Score should be positive")
                      .isPositive();
        System.out.println("overridingErrorMessage passed");

        // lazy supplier - message built only on failure
        String user = "bob";
        assertThat(user).withFailMessage(() -> "User '" + user + "' is invalid")
                        .isNotBlank();
        System.out.println("Lazy message passed");
    }
}

Output

$ mvn clean test -Dtest=*
[INFO] Scanning for projects...
[INFO]
[INFO] ---------< com.logicbig.example:assertj-custom-error-message >----------
[INFO] Building assertj-custom-error-message 1.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- clean:3.2.0:clean (default-clean) @ assertj-custom-error-message ---
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ assertj-custom-error-message ---
[INFO] skip non existing resourceDirectory D:\example-projects\assertj\assertj-custom-error-message\src\main\resources
[INFO]
[INFO] --- compiler:3.11.0:compile (default-compile) @ assertj-custom-error-message ---
[INFO] No sources to compile
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ assertj-custom-error-message ---
[INFO] skip non existing resourceDirectory D:\example-projects\assertj\assertj-custom-error-message\src\test\resources
[INFO]
[INFO] --- compiler:3.11.0:testCompile (default-testCompile) @ assertj-custom-error-message ---
[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-custom-error-message ---
[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.CustomErrorMessageExample
withFailMessage passed
overridingErrorMessage passed
Lazy message passed
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.088 s -- in com.logicbig.example.CustomErrorMessageExample
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.255 s
[INFO] Finished at: 2026-03-03T13:43:11+08:00
[INFO] ------------------------------------------------------------------------

Conclusion

The example passes all assertions with custom messages configured. The value of withFailMessage is visible in test failure scenarios — the domain-specific text replaces AssertJ's generic comparison output, making it immediately clear what the test was checking without reading the assertion code.

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 - Custom Error Messages Select All Download
  • assertj-custom-error-message
    • src
      • test
        • java
          • com
            • logicbig
              • example
                • CustomErrorMessageExample.java

    See Also

    Join