为每个嵌套测试执行 junit5 扩展的 BeforeAll / AfterAll 回调 class。这是预期的吗?

BeforeAll / AfterAll callbacks of junit5 extension are executed for each nested test class. Is this expected?

我有一个测试 class,里面有多个嵌套测试 class。外部测试 class 使用实现 BeforeAllCallback 和 AfterAllCallback 的扩展。这些接口的方法在执行外部测试class时为每个嵌套class调用。这是预期的行为吗?我找不到任何明确说明这一点的文档。

外部测试class 也有@BeforeAll 和@AfterAll 方法。这些在执行外部测试时执行一次class。我有点希望扩展的行为相同。

如果确实存在这种行为,是否有办法抑制它?

这是一个最小的代码示例。非自定义扩展,例如然而,SpringExtension 表现出相同的行为:

@ExtendWith(MyExtension.class)
public class SomeTest {

    @BeforeAll
    static void create() {
        System.out.println("Call beforeAll of test class");
    }

    @AfterAll
    static void destroy() {
        System.out.println("Call afterAll of test class");
    }

    @Nested
    class InnerTest1 {
        @Test
        void testingA() {
            System.out.println("Test 1A");
        }

        @Test
        void testingB() {
            System.out.println("Test 1B");
        }
    }

    @Nested
    class InnerTest2 {
        @Test
        void testingA() {
            System.out.println("Test 2A");
        }

        @Test
        void testingB() {
            System.out.println("Test 2B");
        }
    }
}
public class MyExtension implements BeforeAllCallback, AfterAllCallback {

    public MysqlMockExtension() {
    }

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

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

导致输出:

Call beforeAll of extension
Call beforeAll of test class

Call beforeAll of extension
Test 2A
Test 2B
Call afteeAll of extension

Call beforeAll of extension
Test 1A
Test 1B
Call afteeAll of extension

Call afterAll of test class
Call afteeAll of extension

观察到的行为的原因是您在 Jupiter 中添加到测试 class 的所有扩展都会被其所有子项继承,无论是测试方法还是嵌套测试 classes .你可以做的是检查 class 是否使用了扩展名是顶级 class:

class MyExtension implements BeforeAllCallback {

    @Override
    public void beforeAll(final ExtensionContext extensionContext) throws Exception {
        if (extensionContext.getTestClass().isPresent()) {
            Class<?> currentClass = extensionContext.getTestClass().get();
            if (isNestedClass(currentClass)) {
                return;
            }
        }
        System.out.println("Call beforeAll of extension");
    }

    private boolean isNestedClass(Class<?> currentClass) {
        return !ModifierSupport.isStatic(currentClass) && currentClass.isMemberClass();
    }

}

据我所知,Jupiter 没有限制扩展到 @ExtendWith 注释位置的机制。您可以打开一个问题来请求此功能。