skip to content

Walk through the TestExecutionListener callback lifecycle. What is the difference between prepareTestInstance, beforeTestMethod, and beforeTestExecution, and when does each fire relative to @BeforeEach?

level: middleimportance: should knowfreq 35%

answer

  1. class -> prepareInstance -> method -> execution (body) and back
  2. beforeTestMethod = before @BeforeEach; beforeTestExecution = after it
  3. tx starts in beforeTestMethod (wraps setup)
  4. timing hooks the execution-level callbacks
  5. after* run in reverse listener order

basics

~20 s

prepareTestInstance fires once right after the test object is created (injection happens here). beforeTestMethod fires before each test, before @BeforeEach. beforeTestExecution fires after @BeforeEach, just before the test body runs. after* callbacks mirror them in reverse.

solid answer

~40 s

The TestContextManager drives seven callbacks. Per test class: beforeTestClass and afterTestClass bracket everything. Per test instance: prepareTestInstance runs immediately after instantiation — DependencyInjectionTestExecutionListener autowires the test here. Per method the order is: beforeTestMethod (before @BeforeEach setup), then beforeTestExecution (after setup, immediately before the @Test body), then the test runs, then afterTestExecution (right after the body, before @AfterEach), then afterTestMethod (after teardown). The split between beforeTestMethod and beforeTestExecution was added in Spring 4.3 precisely so a listener can distinguish 'setup phase' from 'the actual test invocation' — e.g. TransactionalTestExecutionListener starts the tx in beforeTestMethod so @BeforeEach runs inside it, while a timing/metrics listener would measure between beforeTestExecution and afterTestExecution to exclude setup cost.

go deeper

for a junior

Know prepareTestInstance = injection, before/after each method exist.

for a middle

Order the seven callbacks and place them around @BeforeEach.

for a senior

Explain why the method-vs-execution split exists (tx vs timing).

for a principal

Reason about PER_CLASS instances, reverse ordering, and dirty-context re-injection.

## The full ordering For a JUnit Jupiter test, the `TestContextManager` interleaves its listener callbacks with the framework's own lifecycle methods. For one test method the sequence is: 1. `beforeTestClass` (once per class, before any instance exists) 2. **test instance constructed** 3. `prepareTestInstance` — the newly created object is passed in; **`DependencyInjectionTestExecutionListener` autowires it here** 4. `beforeTestMethod` 5. `@BeforeEach` / `@Before` setup methods 6. `beforeTestExecution` 7. **the `@Test` method body executes** 8. `afterTestExecution` 9. `@AfterEach` / `@After` teardown methods 10. `afterTestMethod` 11. (repeat 2–10 for each method; with the default per-method instance lifecycle a new instance is created each time) 12. `afterTestClass` (once) ## Why beforeTestMethod AND beforeTestExecution? Before Spring 4.3 there was only `beforeTestMethod`/`afterTestMethod`, which wrap the *entire* method including `@Before`/`@After`. Spring 4.3 added `beforeTestExecution`/`afterTestExecution` that hug **only the test body** (steps 6–8). This distinction is meaningful: - **Transaction management** wants to be *outside* setup, so `TransactionalTestExecutionListener` starts the transaction in `beforeTestMethod` (step 4). That way data seeded in `@BeforeEach` is inside the same transaction and gets rolled back too. - **Timing / observation** wants to measure *only* the test, so it hooks `beforeTestExecution`/`afterTestExecution` (steps 6/8) to exclude fixture cost. `MicrometerObservationRegistryTestExecutionListener` and `ApplicationEventsTestExecutionListener` use the execution-level hooks. ## prepareTestInstance vs beforeTestMethod `prepareTestInstance` fires **once per instance**, right after construction, before any method-level callback. It's the injection point. `beforeTestMethod` fires **per test method**. With per-method test instances (JUnit's default) these appear close together, but with `@TestInstance(PER_CLASS)` or TestNG a single instance can run many methods — then `prepareTestInstance` runs once while `beforeTestMethod` runs many times. A listener that must (re)act per method must not rely solely on `prepareTestInstance`. ## The after* mirror and ordering Listeners are invoked in registered/`@Order` order for the `before*` callbacks and in **reverse** order for the `after*` callbacks — the standard 'nested resource' pattern, so a listener that acquires something early releases it last. ## Gotchas - Exceptions in `beforeTestMethod` abort the method; `afterTestMethod` still runs for listeners that already ran their before-callback. - `afterTestExecution` receives the thrown exception (via `TestContext.getTestException()`), so a listener can inspect pass/fail of just the body. - Injection re-runs: if `@DirtiesContext` marks the context dirty *before* a method, `DependencyInjectionTestExecutionListener` re-injects in `beforeTestMethod`, not only in `prepareTestInstance`.

  • Why does TransactionalTestExecutionListener begin the transaction in beforeTestMethod rather than beforeTestExecution?
    So that @BeforeEach setup (and its DB writes) happens inside the same transaction and is rolled back with the test; execution-level hooks would leave setup outside the tx.
  • How can a listener tell whether the test body passed or threw?
    In afterTestExecution it can call TestContext.getTestException(); a non-null value means the body threw.

saying these in an interview costs you the question

  • Saying beforeTestMethod runs after @BeforeEach (it runs before)
  • Assuming prepareTestInstance runs per method — it's per instance
  • Not knowing after* callbacks fire in reverse order

context