# Assertions, Exceptions and AssertJ — JUnit 5 & Mockito

Source: https://www.skillbyai.com/en/java-testing/j-assertions

> 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.

![A checklist with several lines, most ticked and one crossed, all reported together on one panel.](assets/figures/java-testing/section-2-map.svg) — Figure 2.1 — Grouped assertions report every failing expectation.

## JUnit and AssertJ assertions

Grouped checks, exceptions, collections and BigDecimal comparisons.

```java
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.

**Quiz:** What does assertAll do differently from separate assertions?

- [ ] It runs assertions in parallel threads
- [ ] It ignores failures
- [x] 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.
