自定义测试应用程序上下文



我一直在拼命地尝试构建一个扩展,它需要来自JUnit5扩展模型和Spring Boot Test框架的信息。具体来说,我想使用ApplicationContextInitializer和自定义注释来连接ApplicationContext的创建过程

@Retention(RUNTIME)
@Target(TYPE)
@ContextConfiguration(initializers = CustomContextInitializer.class)
public @interface CustomAnnotation {
String someOption();
}

然后测试看起来是这样的:

@SpringBootTest
@CustomAnnotation(someOption = "Hello There")
public class SomeTest {
...
}

现在,如何从我的CustomContextInitializer中访问测试类的CustomAnnotation实例?

class CustomContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
// How to access the Test Class here?
CustomAnnotation annotation = <Test Class>.getAnnotation(CustomAnnotation.class);
System.out.println(annotation.someOption());
}
}

在创建ApplicationContext期间,是否可以以某种方式访问JUnit5ExtensionContext?它不必来自ApplicationContextInitializer。我只需要一个足够早执行的钩子,这样我就可以在整个bean实例化过程真正开始之前注入一些动态生成的属性。

在bean初始化之前查看@DynamicPropertySource以注入属性。然后,您可以使用@RegisterExtension注册一个自定义扩展,该扩展读取注释属性并通过以下方法使其可用:

@CustomAnnotation(someOption = "Hello There")
public class SomeTest {
@RegisterExtension
static CustomExtension extension = new CustomExtension();
@DynamicPropertySource
static void registerProperties(DynamicPropertyRegistry registry) {
registry.add("property.you.need", 
() -> customExtension.getProperty());
}
}
public class CustomExtension implements BeforeAllCallback {
private String property;
public String getProperty() {
return property;
}
@Override
public void beforeAll(ExtensionContext context) throws Exception {
CustomAnnotation annotation = context.getRequiredTestClass()
.getAnnotation(CustomAnnotation.class);
property = annotation.someOption();
}
}

我知道它不能回答将JUnit5与Spring初始化机制挂钩的问题,但如果您只需要动态属性,那么它就可以解决这个问题。

您可以实现自己的TestExecutionListener,并使用它访问您提到的注释

@Retention(RUNTIME)
@Target(ElementType.TYPE)
@TestExecutionListeners(listeners = CustomTestExecutionListener.class, mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS)
@interface CustomAnnotation {
String someOption();
}
static class CustomTestExecutionListener implements TestExecutionListener {
@Override
public void beforeTestClass(TestContext testContext) throws Exception {
final CustomAnnotation annotation = testContext.getTestClass().getAnnotation(CustomAnnotation.class);
System.out.println(annotation.someOption());
}
}

相关内容

最新更新