In JUnit 5, a test method lives in a class annotated @Nested inside an outer test class, and both classes declare @BeforeEach and @AfterEach methods. In what order do those four methods run around the test?
answer
- outside-in setup, inside-out teardown
- nested try/finally shape
- same rule as superclass/subclass hooks
- outer @BeforeAll covers nested tests too
- two instances: outer + inner per test
basics
~10 sOuter @BeforeEach runs first, then the nested class's @BeforeEach, then the test, then the nested @AfterEach, then the outer @AfterEach. Setup runs outside-in, teardown inside-out — like nested try/finally blocks.
solid answer
~50 sSetup runs **outside-in** and teardown **inside-out**: 1. outer class `@BeforeEach` 2. nested class `@BeforeEach` 3. the `@Test` method 4. nested class `@AfterEach` 5. outer class `@AfterEach` The rule generalizes: with several levels of nesting, every enclosing level's `@BeforeEach` runs before the level below it, and the `@AfterEach` methods unwind in reverse. It is the same ordering JUnit applies to inheritance — superclass setup first, subclass teardown first — and the same shape as nested `try { ... } finally { ... }` blocks. That is exactly why `@Nested` is useful for fixtures: the outer setup establishes the common precondition, and each nested class layers its own scenario on top without repeating it. `@AfterEach` methods run even when the test or an earlier `@AfterEach` fails, and Jupiter reports all failures rather than swallowing later ones. One more level: an outer `@BeforeAll` runs once before every test in the whole tree, nested classes included.
code
java · 15 linesclass CartTest {
@BeforeEach void outerSetup() { System.out.println("1 outer before"); }
@AfterEach void outerTeardown() { System.out.println("5 outer after"); }
@Nested
class WhenOneItemAdded {
@BeforeEach void innerSetup() { System.out.println("2 inner before"); }
@AfterEach void innerTeardown() { System.out.println("4 inner after"); }
@Test
void totalsTheItem() { System.out.println("3 test"); }
}
}go deeper
Recite the five-step order and the phrase 'setup outside-in, teardown inside-out'.
Add the try/finally model, the parallel with superclass/subclass hook ordering, and where the outer @BeforeAll sits.
Bring in the practical consequence — the outer level owns the shared precondition, extensions registered outside apply to nested classes — plus teardown-on-failure semantics.
Discuss when this layering earns its complexity versus explicit fixture factories, and what deep hierarchies cost a reader.
## What @Nested is In JUnit Jupiter, `@Nested` marks a **non-static inner class** inside a test class as a test class in its own right. It exists to express a hierarchy of scenarios — "when the cart is empty", "when the cart has one item" — where each level adds setup on top of the level above it. The reason the ordering question comes up in interviews is that this layering is only useful if you know exactly when each layer's hooks fire. ## The ordering rule For a test method inside a nested class, with `@BeforeEach`/`@AfterEach` declared at both levels: ``` outer @BeforeEach nested @BeforeEach @Test nested @AfterEach outer @AfterEach ``` So **setup is outside-in, teardown is inside-out**. Three levels of nesting simply extend the ladder: level 1 setup, level 2 setup, level 3 setup, test, level 3 teardown, level 2 teardown, level 1 teardown. The mental model that never fails is nested `try/finally`: each enclosing class wraps the one inside it, so whatever the outer level set up is still valid while the inner level runs, and the outer level cleans up last — after everything that depended on it has finished. The same principle governs inheritance: a superclass `@BeforeEach` runs before the subclass's, and the subclass's `@AfterEach` runs before the superclass's. `@Nested` is the composition-flavored version of the same idea. ## Where the class-level hooks fit `@BeforeAll` in the **outer** class runs once, before any test in the outer class *or in any nested class* — the nested classes are part of the outer class's test tree, so their tests are covered by it. `@AfterAll` in the outer class correspondingly runs after the last test anywhere in that tree. Class-level hooks in the nested class are the constrained case: an inner class historically cannot declare `static` members, so a nested `@BeforeAll` either requires `@TestInstance(Lifecycle.PER_CLASS)` on the nested class or a sufficiently modern Java language level and JUnit version. That is a separate discussion; for `@BeforeEach`/`@AfterEach` there is no such restriction at any level. ## Instances, not just methods Under the default per-method lifecycle, running one test in a nested class requires **two** objects: an instance of the outer class and an instance of the nested class bound to it (that is what "non-static inner class" buys you — the inner instance holds a reference to its enclosing instance). Both are created fresh for each test method. The outer `@BeforeEach` runs on the outer instance, the nested one on the nested instance, and the nested test can read the outer instance's fields directly. This is why the ordering matters so concretely: the outer `@BeforeEach` is what puts the outer fields into a usable state before the inner setup — and before the test — touches them. ## Failure semantics - If the **outer `@BeforeEach` throws**, the nested `@BeforeEach` and the test do not run, and Jupiter unwinds by running the teardown callbacks that correspond to the setup that had already begun; teardown is not skipped merely because something failed. - If the **test throws**, all `@AfterEach` methods still run, inner before outer. - If **several `@AfterEach` methods throw**, Jupiter records all of them (as suppressed exceptions on the reported failure) rather than reporting only the first — a detail that saves real debugging time. ## Multiple hooks at the same level Within one class, the relative order of several `@BeforeEach` methods is **not guaranteed by declaration order**; Jupiter deliberately leaves it deterministic-but-unspecified so you do not build dependencies between them. If ordering between two setup steps matters, put them in one method, or split them across levels of the hierarchy where the order *is* defined. There is an `@Order`-style mechanism for test methods, but the right fix for hooks is usually to remove the dependency. ## Extensions interleave the same way Registered extension callbacks (`BeforeEachCallback`, `AfterEachCallback`) follow the same outside-in/inside-out wrapping relative to the hierarchy, and extensions registered on the outer class also apply to nested classes — they are inherited down the tree. So an extension declared once on the outer class covers every scenario class beneath it, which is a common reason to structure tests this way. ## How to answer in an interview Give the five-step order, then the one-line rule ("setup outside-in, teardown inside-out, like nested try/finally"), then one consequence you have actually relied on — usually "the outer level owns the shared precondition so each nested scenario does not repeat it". That trio is a complete answer in under thirty seconds.
- Where does an outer class's @BeforeAll fit into that sequence?It runs once, before any test in the whole tree — including every test inside the nested classes — because nested classes are part of the enclosing class's test tree. The matching @AfterAll runs once after the last test anywhere beneath it. So the full sequence for the first nested test is: outer @BeforeAll, outer @BeforeEach, nested @BeforeEach, test, nested @AfterEach, outer @AfterEach.
- Two @BeforeEach methods are declared in the same class and one depends on the other having run. Is that safe?No. JUnit Jupiter does not guarantee that multiple lifecycle methods declared in the same class run in declaration order; the order is deterministic but intentionally unspecified so that tests do not encode dependencies between hooks. If two setup steps are ordered, merge them into a single method, or move one to an enclosing class level where the outside-in ordering is guaranteed.
- If the test method fails, do the @AfterEach methods still run?Yes. Teardown runs regardless of the test's outcome, inner class first and then outer, mirroring a finally block. If several @AfterEach methods themselves throw, Jupiter aggregates the failures rather than reporting only the first, so you see every teardown problem in the report.
Getting dressed and undressed: coat goes on last and comes off first, base layer goes on first and comes off last.
saying these in an interview costs you the question
- Saying the nested @BeforeEach runs before the outer one
- Expecting teardown to run in the same direction as setup instead of unwinding
- Assuming an outer @BeforeAll does not apply to tests inside nested classes
- Believing multiple @BeforeEach methods in one class are ordered by declaration order
- Thinking @AfterEach is skipped when the test fails