javajunit5junit5-extension-model

How to create Extension which runs beforeAll only once for whole big class with many nested classes inside


Given my tested class with many nested classes inside:

class TestWithManyNested {

    @RegisterExtension
    static MyExtension extension = new MyExtension();

    @Nested
    class Nested1 {

        @Test
        void nested1() {
        }
    }

    @Nested
    class Nested2 {

        @Test
        void nested2() {
        }
    }
}

Here is my simple extension:

static class MyExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback {

        @Override
        public void beforeAll(ExtensionContext extensionContext) throws Exception {
            System.out.println("beforeAll");
        }

        @Override
        public void afterAll(ExtensionContext extensionContext) throws Exception {
            System.out.println("afterAll");
        }
    }

How can I run my TestWithManyNested with MyExtension which just run beforeAll only once for whole test


Solution

  • If you only want the class-level callbacks to execute for the outermost class, you can rewrite your extension as follows (checking that there is no "enclosing class" for the outermost class).

    static class MyExtension implements BeforeAllCallback, AfterAllCallback {
    
        @Override
        public void beforeAll(ExtensionContext extensionContext) throws Exception {
            Class<?> testClass = extensionContext.getRequiredTestClass();
            if (testClass.getEnclosingClass() == null) {
                System.err.println("beforeAll: " + testClass.getName());
            }
        }
    
        @Override
        public void afterAll(ExtensionContext extensionContext) throws Exception {
            Class<?> testClass = extensionContext.getRequiredTestClass();
            if (testClass.getEnclosingClass() == null) {
                System.err.println("afterAll: " + testClass.getName());
            }
        }
    }