What do @BeforeEach and @AfterEach do in JUnit 5, and why would you use them?
answer
- Before/After EACH @Test method (per-test, not per-class)
- @BeforeEach = build fresh fixture; @AfterEach = cleanup, runs even on failure
- Non-static, non-private (instance lifecycle)
- New test-class instance per method by default (PER_METHOD)
- Goal: test isolation / independence
basics
~20 s@BeforeEach runs before every test method and @AfterEach runs after each one. You use them to set up a fresh starting state (like creating objects) before each test and to clean up afterward, so tests don't affect each other.
solid answer
~40 sIn JUnit 5, a method annotated @BeforeEach runs once before each @Test method, and @AfterEach runs once after each. They give every test a fresh fixture: @BeforeEach typically constructs the object under test and its dependencies so each test starts from a known state, and @AfterEach releases resources (close files, roll back data) regardless of whether the test passed or failed. Because JUnit creates a new test-class instance per test method by default, fields reset anyway, but @BeforeEach is where you do the active setup. This enforces test isolation and independence: no test should rely on state left by another. Both methods must be non-private and non-static (instance lifecycle), can be inherited from superclasses, and you may have several of them.
go deeper
Can state that @BeforeEach runs before each test and @AfterEach after each, and that they're for setup and cleanup to keep tests independent.
Explains the per-method fresh-instance lifecycle, that @AfterEach runs even on failure, and the non-static/non-private rule; contrasts with @BeforeAll/@AfterAll.
Articulates test-isolation rationale, inheritance ordering (super before/after sub), multiple-method ordering caveats, and the PER_METHOD vs PER_CLASS lifecycle trade-off.
Frames fixture strategy across a suite: when to push shared setup into a base class vs extensions, costs of PER_CLASS reuse, and how lifecycle choices affect parallel execution and flakiness at scale.
## The problem these solve A **unit test** is a small program that checks one behavior of your code by setting up some inputs, running the code, and asserting the result. In JUnit 5 (the modern Java testing framework, also called *Jupiter*), each test is a method annotated with **`@Test`**. A test class usually holds several such methods. Every test needs a clean starting point — a **fixture**, which just means the set of objects and state a test operates on (e.g. the object you're testing plus any fake dependencies). If one test mutates a shared object and the next test sees those changes, tests become coupled and flaky: they pass or fail depending on *order*. The cure is **test isolation** — each test starts from a known, fresh state and leaves no trace behind. ## What the annotations do - **`@BeforeEach`** marks a method that JUnit runs *once before each* `@Test` method in the class. If there are 5 tests, a `@BeforeEach` method runs 5 times — right before each test. This is where you build the fixture: `new` up the object under test, reset counters, open a connection, etc. - **`@AfterEach`** marks a method JUnit runs *once after each* `@Test` method, **even if the test threw an exception or failed an assertion**. This is where you tear down: close files, shut down a connection, delete temp data. So the per-test lifecycle is: `@BeforeEach` → the `@Test` body → `@AfterEach`, repeated for every test. ## Fresh instance per test By default JUnit 5 uses **`PER_METHOD` test instance lifecycle**: it creates a *brand-new instance of the test class for every test method*. That means instance fields are re-initialized for each test automatically — a half of the isolation story. `@BeforeEach` is the place to do the *active* work that field initializers can't easily express (e.g. wiring several objects together, seeding data). (You can switch to `@TestInstance(Lifecycle.PER_CLASS)` to reuse one instance, but then you must be more careful about residual state.) ## Rules for the methods - The annotated methods must return `void` and **must not be `private` or `static`** (they run on the instance). A common beginner bug is making them `static` — JUnit will refuse to run them or report a configuration error. (Contrast: `@BeforeAll`/`@AfterAll`, which run once for the whole class, *must* be `static` under the default lifecycle.) - You can declare **more than one** `@BeforeEach`/`@AfterEach`; JUnit runs them all, but their *relative order within one class is not guaranteed* — don't depend on it. - They can throw exceptions; a thrown exception in `@BeforeEach` aborts that test (it's reported as failed/errored) and JUnit skips the test body but still runs `@AfterEach` for any setup that completed. ## Inheritance and ordering across a hierarchy If your test class extends a base test class, the lifecycle methods are inherited (as long as they aren't overridden/hidden). JUnit runs **superclass `@BeforeEach` methods before subclass ones** (top-down, like constructor chaining), and **superclass `@AfterEach` methods after subclass ones** (bottom-up) — a symmetric nesting. This lets a shared base set up common scaffolding for all subclasses. ## Relation to the older JUnit 4 JUnit 5 renamed JUnit 4's `@Before`/`@After` to `@BeforeEach`/`@AfterEach` (and `@BeforeClass`/`@AfterClass` to `@BeforeAll`/`@AfterAll`). The behavior is the same idea; only the names and import packages (`org.junit.jupiter.api.*`) changed. ## Putting it together Use `@BeforeEach` to remove duplicated setup from the top of every test and to guarantee each test starts clean; use `@AfterEach` for deterministic cleanup. The payoff is independent, order-insensitive, repeatable tests.
- Does @AfterEach run if the @Test method throws an exception?Yes. @AfterEach is designed to run after each test regardless of the test's outcome, so cleanup is deterministic. The only thing that can skip it is a failure in setup that prevented the relevant resource from being created, or a JVM crash.
- If a field is initialized in a field initializer, why also use @BeforeEach?Both work for simple cases because a new instance is created per test. @BeforeEach is preferred when setup needs logic (wiring multiple objects, conditional seeding) or must run as part of the documented lifecycle, and it keeps setup visible and uniform.
saying these in an interview costs you the question
- Saying @BeforeEach runs only once for the whole class (that's @BeforeAll)
- Declaring @BeforeEach/@AfterEach static under the default lifecycle
- Claiming @AfterEach is skipped when a test fails (it still runs)
- Confusing JUnit 4 @Before with @BeforeEach behavior differences