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

b15*_*b15 7 java junit junit5

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

鉴于:

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

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

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

    ...
}
Run Code Online (Sandbox Code Playgroud)

myField如何从我的测试课程访问?

Ale*_*rov 4

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

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

@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyField {
}
Run Code Online (Sandbox Code Playgroud)

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

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. 
    }

}
Run Code Online (Sandbox Code Playgroud)

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

@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
    }

}
Run Code Online (Sandbox Code Playgroud)

注意:您也可以BeforeAllCallback根据您的实际需求扩展在类的所有测试方法之前执行一次。