JUnit5:从测试访问扩展字段 class

JUnit5: access extension field from test class

我需要在 class 中使用它的所有测试用例之前和之后使用 运行 代码的扩展。我的测试 classes 需要访问我的扩展 class 中的一个字段。这可能吗?

鉴于:

@ExtendWith(MyExtension.class)
public class MyTestClass {
    
    @Test
    public void test() {
        // get myField from extension and use it in the test
    }
}

public class MyExtension implements 
  BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback {
    
    private int myField;

    public MyExtension() {
        myField = someLogic();
    }

    ...
}

如何从我的测试 class 访问 myField

您可以通过标记注释和 BeforeEachCallback 扩展来实现。

创建一个特殊的标记注释,例如

@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyField {
}

使用注释从扩展中查找和设置值:

import org.junit.jupiter.api.extension.BeforeEachCallback;

public class MyExtension implements BeforeEachCallback {

    @Override
    public void beforeEach(final ExtensionContext context) throws Exception {
        // Get the list of test instances (instances of test classes) 
        final List<Object> testInstances = 
            context.getRequiredTestInstances().getAllInstances();
        
        // Find all fields annotated with @MyField
        // in all testInstances objects.
        // You may use a utility library of your choice for this task. 
        // See for example, https://github.com/ronmamo/reflections 
        // I've omitted this boilerplate code here. 

        // Assign the annotated field's value via reflection. 
        // I've omitted this boilerplate code here. 
    }

}

然后,在您的测试中,您注释目标字段并使用您的扩展名扩展测试:

@ExtendWith(MyExtension.class)
public class MyTestClass {

    @MyField
    int myField;

    @Test
    public void test() {
        // use myField which has been assigned by the extension before test execution
    }

}

注意:您也可以扩展BeforeAllCallback,它在class的所有测试方法之前执行一次,具体取决于您的实际需求。