Lesson 4 / 25
Assertions, Exceptions and AssertJ
Write precise assertions for values, collections, exceptions and grouped checks.
Saying exactly what you expect
JUnit's Assertions class covers the basics: assertEquals, assertNotEquals, assertTrue/assertFalse, assertNull/assertNotNull, assertSame (identity), assertArrayEquals and assertIterableEquals. assertThrows(Type.class, executable) checks that code throws and returns the exception for further checks; assertDoesNotThrow documents the opposite. assertAll groups several assertions and reports all failures together instead of stopping at the first. assertTimeout fails if code takes too long. For floating point, pass a delta: assertEquals(0.3, sum, 1e-9). Many teams prefer AssertJ for readable, chainable assertions with excellent failure messages: assertThat(list).hasSize(3).containsExactly("a", "b", "c"), assertThat(order.total()).isEqualByComparingTo("499.00") for BigDecimal, assertThatThrownBy(...).isInstanceOf(...).hasMessageContaining(...), and extracting to check fields of objects in collections. Whichever you use, assert the specific outcome that matters, not just that something is non-null.
Precise assertions
Grouped and fluent assertions report exactly which expectations failed.
JUnit and AssertJ assertions
Grouped checks, exceptions, collections and BigDecimal comparisons.
import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
@Test
void orderTotalsAreCalculated() {
Order order = Order.of(line("pen", 2, "49.50"), line("notebook", 1, "120.00"));
assertAll("order",
() -> assertEquals(2, order.lines().size()),
() -> assertThat(order.total()).isEqualByComparingTo("219.00"), // 219.0 == 219.00
() -> assertThat(order.status()).isEqualTo(OrderStatus.DRAFT));
}
@Test
void lineSkusAreKeptInOrder() {
Order order = Order.of(line("pen", 1, "10"), line("ink", 1, "20"));
assertThat(order.lines())
.extracting(OrderLine::sku)
.containsExactly("pen", "ink");
}
@Test
void emptyOrderCannotBePlaced() {
Order order = Order.of();
assertThatThrownBy(order::place)
.isInstanceOf(IllegalStateException.class)
.hasMessageContaining("at least one line");
}BigDecimal equals checks scale
new BigDecimal("219.0").equals(new BigDecimal("219.00")) is false because the scales differ. Use AssertJ's isEqualByComparingTo or compare with compareTo when checking money.
Quick check: What does assertAll do differently from separate assertions?
- It runs assertions in parallel threads
- It ignores failures
- It executes all grouped assertions and reports every failure together
- It only works with AssertJ
Answer
It executes all grouped assertions and reports every failure together — assertAll collects failures instead of stopping at the first failing assertion.