Precise assertions
While contains()
verifies that specific elements are present in a collection, it doesn't ensure that only those elements exist.
AssertJ provides exact assertions that verify the complete contents of a collection, ensuring no unexpected elements are present.
From partial to exact verification
The contains()
assertion is useful when you only care about certain elements being present.
However, when you need to verify the complete contents of a collection, exact assertions provide stronger guarantees.
- Before
- After
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
class AssertListExact {
List<String> list = List.of("a", "b", "c");
@Test
void assertMultipleElements() {
assertThat(list).contains("a", "b", "c");
}
}
contains()
only verifies the specified elements are present. The collection could contain additional unexpected elements and the test would still pass.
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
class AssertListExact {
List<String> list = List.of("a", "b", "c");
@Test
void assertMultipleElements() {
assertThat(list).containsExactly("a", "b", "c");
// Or if order doesn't matter:
assertThat(list).containsExactlyInAnyOrder("a", "b", "c");
}
}
containsExactly()
verifies the collection contains exactly these elements in the specified order.
containsExactlyInAnyOrder()
verifies the collection contains exactly these elements—no more, no less—making your test more precise.
From chained to exact assertions
When you find yourself chaining hasSize()
, contains()
, and doesNotContain()
together, this is often a sign that an exact assertion would better express your intent.
- Before
- After
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
class ExactAssertJTest {
@Test
void bundle() {
List<Book> books = new Bundle().getBooks();
assertThat(books)
.hasSize(3)
.contains(
new Book("Effective Java", "Joshua Bloch", 2001),
new Book("Java Concurrency in Practice", "Brian Goetz", 2006),
new Book("Clean Code", "Robert C. Martin", 2008))
.doesNotContain(new Book("Java 8 in Action", "Raoul-Gabriel Urma", 2014));
}
}
Chaining hasSize()
, contains()
, and doesNotContain()
requires multiple assertions and still doesn't guarantee no unexpected elements exist.
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
class ExactAssertJTest {
@Test
void bundle() {
List<Book> books = new Bundle().getBooks();
assertThat(books)
.containsExactlyInAnyOrder(
new Book("Effective Java", "Joshua Bloch", 2001),
new Book("Java Concurrency in Practice", "Brian Goetz", 2006),
new Book("Clean Code", "Robert C. Martin", 2008));
}
}
Using containsExactlyInAnyOrder()
replaces three separate checks (size, contains, and implicit no-extras) with a single precise assertion.
Choosing the right assertion
AssertJ provides several exact collection assertions, each with specific semantics:
containsExactly(...)
- Verifies the collection contains exactly the given elements in that ordercontainsExactlyInAnyOrder(...)
- Verifies the collection contains exactly the given elements in any ordercontainsOnly(...)
- Verifies the collection contains only the given elements, allowing duplicates
- Order matters
- Order doesn't matter
- Duplicates allowed
@Test
void ordered() {
List<String> steps = getWorkflowSteps();
// Verifies exact order
assertThat(steps).containsExactly("Init", "Process", "Validate", "Complete");
}
@Test
void unordered() {
Set<String> tags = getArticleTags();
// Verifies exact content, any order
assertThat(tags).containsExactlyInAnyOrder("java", "testing", "assertj");
}
@Test
void withDuplicates() {
List<String> values = List.of("A", "B", "A", "C", "B");
// Verifies only these elements exist, duplicates allowed
assertThat(values).containsOnly("A", "B", "C");
}
Choose the most precise assertion that matches your intent. This makes tests self-documenting and provides clearer failure messages when expectations aren't met.