问题描述
JUnit Jupiter(JUnit 5)中是否有一种方法可以将Spring组件注入到TestTemplateInvocationContextProvider
中?
Is there a way in JUnit Jupiter (JUnit 5) that makes it possible to inject Spring components into a TestTemplateInvocationContextProvider
?
推荐答案
是的,如果您在为测试类加载的Spring ApplicationContext
中将TestTemplateInvocationContextProvider
注册为bean,则可以让提供程序@Autowired
字段并使用@RegisterExtension
注册为JUnit Jupiter扩展.诀窍在于,您将需要使用每类测试实例的生命周期模式,以使提早注册提供者,以便JUnit Jupiter可以使用它.
Yes, if you register your TestTemplateInvocationContextProvider
as a bean in the Spring ApplicationContext
loaded for your test class, you can then have the provider @Autowired
into a field and registered as a JUnit Jupiter extension using @RegisterExtension
. The trick is that you'll need to use the per-class test instance lifecycle mode in order for the provider to be registered early enough for JUnit Jupiter to use it.
以下是《 JUnit 5用户指南》中TestTemplateDemo
的修改版本.
The following is a modified version of TestTemplateDemo
from the JUnit 5 User Guide.
测试按原样"通过,但是您可以从@Bean
声明的@Bean
声明中删除//
,以查看测试失败.
The tests pass "as is", but you can remove the //
from the @Bean
declaration for the baz
bean to see a test fail.
@SpringJUnitConfig
@TestInstance(Lifecycle.PER_CLASS)
class TestTemplateDemo {
@Autowired
@RegisterExtension
TestTemplateInvocationContextProvider testTemplateInvocationContextProvider;
@TestTemplate
void testTemplate(String parameter) {
assertTrue("foo".equals(parameter) || "bar".equals(parameter));
}
@Configuration
static class Config {
@Bean
String foo() {
return "foo";
}
@Bean
String bar() {
return "bar";
}
// @Bean
String baz() {
return "baz";
}
@Bean
TestTemplateInvocationContextProvider myTestTemplateInvocationContextProvider(
List<String> parameters) {
return new MyTestTemplateInvocationContextProvider(parameters);
}
}
public static class MyTestTemplateInvocationContextProvider
implements TestTemplateInvocationContextProvider {
private final List<String> parameters;
public MyTestTemplateInvocationContextProvider(List<String> parameters) {
this.parameters = parameters;
}
@Override
public boolean supportsTestTemplate(ExtensionContext context) {
return true;
}
@Override
public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(
ExtensionContext context) {
return this.parameters.stream().map(p -> invocationContext(p));
}
private TestTemplateInvocationContext invocationContext(String parameter) {
return new TestTemplateInvocationContext() {
@Override
public String getDisplayName(int invocationIndex) {
return parameter;
}
@Override
public List<Extension> getAdditionalExtensions() {
return Collections.singletonList(new ParameterResolver() {
@Override
public boolean supportsParameter(
ParameterContext parameterContext,
ExtensionContext extensionContext) {
return parameterContext.getParameter().getType().equals(
String.class);
}
@Override
public Object resolveParameter(ParameterContext parameterContext,
ExtensionContext extensionContext) {
return parameter;
}
});
}
};
}
}
}
这篇关于JUNIT 5:将弹簧组件注入到自定义TestTemplateInvocationContextProvider中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!