Skip to main content

Custom assertions

AssertJ allows you to create custom assertion classes for your domain objects, making tests more readable and expressive. Custom assertions provide fluent APIs tailored to your domain, reducing boilerplate and improving maintainability.

Domain-specific assertions

Instead of repeatedly extracting properties and asserting on them, create custom assertion classes.

BookTest.java
import com.github.timtebeek.books.Book;
import org.junit.jupiter.api.Test;

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

class BookTest {

@Test
void verifyBook() {
Book book = new Book("Effective Java", "Joshua Bloch", 2001);

assertThat(book.getTitle()).contains("Effective");
assertThat(book.getAuthor()).contains("Bloch");
assertThat(book.getYear()).isLessThan(2003);
}

@Test
void verifyAnotherBook() {
Book book = new Book("Clean Code", "Robert C. Martin", 2008);

assertThat(book.getTitle()).contains("Clean");
assertThat(book.getAuthor()).contains("Martin");
assertThat(book.getYear()).isLessThan(2010);
}
}
warning

Repeatedly extracting and asserting on the same properties across multiple tests becomes verbose and repetitive.

Exact match assertions

Custom assertions can provide convenience methods for common assertion patterns.

BookTest.java
import com.github.timtebeek.books.Book;
import org.junit.jupiter.api.Test;

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

class BookTest {

@Test
void verifyExactMatch() {
BookTester bookTester = BookTester.of(new Book("Effective Java", "Joshua Bloch", 2001));

assertThat(bookTester).title().isEqualTo("Effective Java");
assertThat(bookTester).author().isEqualTo("Joshua Bloch");
assertThat(bookTester).year().isEqualTo(2001);
}
}
info

While the property accessors work well, exact match assertions can be even more concise.

Collection assertions

Custom assertions work seamlessly with collection assertions using map() and allSatisfy().

BundleTest.java
import com.github.timtebeek.books.Book;
import com.github.timtebeek.books.Bundle;
import org.junit.jupiter.api.Test;

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

class BundleTest {

@Test
void allBooksFromEarlierDecade() {
assertThat(new Bundle().getBooks())
.allSatisfy(book -> {
assertThat(book.getYear()).isBetween(1999, 2010);
});
}
}
info

While this works, it doesn't leverage the custom assertion we created.

Satisfies with custom assertions

Custom assertions can be used with satisfies() to verify multiple conditions on an object.

BookTest.java
import com.github.timtebeek.books.Book;
import org.junit.jupiter.api.Test;

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

class BookTest {

@Test
void verifyMultipleConditions() {
Book book = new Book("Effective Java", "Joshua Bloch", 2001);

assertThat(book).satisfies(
b -> assertThat(b.getTitle()).contains("Effective"),
b -> assertThat(b.getAuthor()).contains("Bloch"),
b -> assertThat(b.getYear()).isLessThan(2003)
);
}
}
info

Using satisfies() with multiple lambdas works but requires manual property extraction.