From 1c207cf94c8bbe750e1f708721abc256ec32987c Mon Sep 17 00:00:00 2001 From: Zakaria El Orche Date: Wed, 9 Sep 2026 11:05:06 +0000 Subject: [PATCH] feat(testing): boot lazily instead of eagerly in beforeEach MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit beforeEach called ensureStarted(), so every FlashTest field in a class booted for every test whether or not that test touched it — a class holding four servers paid for four boots per test. Booting is already lazy on first access, so the hook was only ever forcing work forward. Neither hook starts anything now. beforeAll still records that a static field owns the class-scoped lifecycle, which is what keeps afterEach from tearing a class-scoped server down after the first test. This also lets an application read @TempDir inside configure(): JUnit populates those during instance post-processing, before the first test body but after extension beforeEach callbacks would have fired. Co-Authored-By: Claude Opus 5 --- .../src/main/java/dev/relism/flash/testing/FlashTest.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/flash-testing/src/main/java/dev/relism/flash/testing/FlashTest.java b/flash-testing/src/main/java/dev/relism/flash/testing/FlashTest.java index 666d821..18605e6 100644 --- a/flash-testing/src/main/java/dev/relism/flash/testing/FlashTest.java +++ b/flash-testing/src/main/java/dev/relism/flash/testing/FlashTest.java @@ -165,10 +165,14 @@ public final class FlashTest implements BeforeAllCallback, AfterAllCallback, // ── JUnit lifecycle ────────────────────────────────────────────────────── // A static field receives class- AND method-level callbacks, so afterEach would otherwise // tear the server down after the first test. classScoped records which tier owns it. + // + // Neither hook starts anything: booting stays lazy, so a class holding several servers + // only pays for the ones a test actually touches, and an application whose configure() + // reads @TempDir sees it populated rather than null. - @Override public void beforeAll(ExtensionContext context) { classScoped = true; ensureStarted(); } + @Override public void beforeAll(ExtensionContext context) { classScoped = true; } @Override public void afterAll(ExtensionContext context) { stop(); } - @Override public void beforeEach(ExtensionContext context) { if (!classScoped) ensureStarted(); } + @Override public void beforeEach(ExtensionContext context) { /* lazy */ } @Override public void afterEach(ExtensionContext context) { if (!classScoped) stop(); } // ── Internals ────────────────────────────────────────────────────────────