AssertJ is a fluent assertion library that works with JUnit and TestNG. Instead of assertEquals(expected, actual), you chain readable checks from the actual value, assertThat(names).hasSize(3).contains("Alice"), and get far clearer failure messages, especially for collections and objects.
// AssertJ: more readable assertions than JUnit's assertEquals
import static org.assertj.core.api.Assertions.*;
// Basic assertions
assertThat("Hello World")
.isNotNull()
.isNotEmpty()
.startsWith("Hello")
.endsWith("World")
.contains("lo W")
.hasSize(11)
.isEqualToIgnoringCase("hello world");
// Number assertions
assertThat(42)
.isPositive()
.isGreaterThan(10)
.isLessThanOrEqualTo(100)
.isBetween(0, 100)
.isEven();
// Collection assertions
List<String> names = List.of("Alice", "Bob", "Charlie");
assertThat(names)
.hasSize(3)
.contains("Alice", "Bob")
.containsExactly("Alice", "Bob", "Charlie")
.doesNotContain("Dave")
.allMatch(s -> s.length() > 2)
.anyMatch(s -> s.startsWith("A"))
.noneMatch(String::isEmpty);
// Object assertions
User user = new User("Alice", 30, "alice@test.com");
assertThat(user)
.isNotNull()
.hasFieldOrPropertyWithValue("name", "Alice")
.hasFieldOrPropertyWithValue("age", 30);
// Exception assertions
assertThatThrownBy(() -> Integer.parseInt("abc"))
.isInstanceOf(NumberFormatException.class)
.hasMessageContaining("abc");
assertThatCode(() -> safeMethod()).doesNotThrowAnyException();
// Custom error message
assertThat(user.getAge())
.as("User age should be adult")
.isGreaterThanOrEqualTo(18);
Setup
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.26.0</version> <!-- check Maven Central for the latest -->
<scope>test</scope>
</dependency>
Extracting Values from Lists of Objects
List<Product> products = api.getProducts();
assertThat(products)
.extracting(Product::name)
.containsExactly("Backpack", "Bike Light", "Bolt T-Shirt");
assertThat(products)
.extracting(Product::name, Product::price)
.contains(tuple("Backpack", 29.99));
assertThat(products).filteredOn(p -> p.price() > 20).hasSize(2);
Comparing Whole Objects
// Field-by-field comparison without needing equals(), ignoring generated fields
assertThat(actualUser)
.usingRecursiveComparison()
.ignoringFields("id", "createdAt")
.isEqualTo(expectedUser);
Soft Assertions
SoftAssertions.assertSoftly(softly -> {
softly.assertThat(page.getTitle()).isEqualTo("Checkout");
softly.assertThat(page.getTotal()).isEqualTo("₹1,299");
softly.assertThat(page.isPayButtonEnabled()).isTrue();
}); // reports all failures together
assertSoftly calls assertAll() for you, which avoids the classic TestNG SoftAssert bug of forgetting it.
Most-Used AssertJ Assertions
| Type | Assertions |
|---|---|
| Any object | isEqualTo, isNotNull, isInstanceOf, isIn, usingRecursiveComparison() |
| String | contains, startsWith, matches(regex), isEqualToIgnoringCase, isBlank |
| Number | isPositive, isBetween, isCloseTo(x, within(0.01)) |
| Collection | hasSize, contains, containsExactly, containsExactlyInAnyOrder, isSorted, allMatch, extracting |
| Map | containsKey, containsEntry, doesNotContainKey |
| Exception | assertThatThrownBy(...), isInstanceOf, hasMessageContaining, assertThatCode(...).doesNotThrowAnyException() |
| Optional | isPresent, isEmpty, hasValue |
AssertJ in UI and API Tests
// Selenium: verify sorted prices on a listing page
List<Double> prices = driver.findElements(By.cssSelector(".price")).stream()
.map(e -> Double.parseDouble(e.getText().replaceAll("[^0-9.]", "")))
.toList();
assertThat(prices).as("prices sorted low to high").isSorted();
// REST Assured: deserialize, then assert with AssertJ
List<String> emails = given().get("/users").jsonPath().getList("data.email");
assertThat(emails).isNotEmpty().allMatch(e -> e.endsWith("@example.com"));
The as(...) description appears in the failure message, so a failing CI run tells you what was being checked without opening the code.
FAQs
Is AssertJ better than JUnit or TestNG assertions?
It is more readable and gives clearer failure messages, especially for collections and objects, and works with both frameworks. Many teams use AssertJ for assertions while keeping JUnit or TestNG as the runner.
Does AssertJ work with TestNG?
Yes. AssertJ only provides assertions, so it works with any runner; import org.assertj.core.api.Assertions.assertThat in your TestNG tests.
How do I add a custom message to an AssertJ assertion?
Call .as("description") (or .describedAs) before the assertion method; the text appears in the failure message.