JUNIT 5:将 spring 组件注入自定义 TestTemplateInvocationContextProvider
JUNIT 5: Inject spring components to custom TestTemplateInvocationContextProvider
JUnit Jupiter (JUnit 5) 中是否有一种方法可以将 Spring 组件注入 TestTemplateInvocationContextProvider
?
是的,如果您在为测试 class 加载的 Spring ApplicationContext
中将您的 TestTemplateInvocationContextProvider
注册为 bean,然后您可以让提供程序 @Autowired
到一个字段中,并使用 @RegisterExtension
注册为 JUnit Jupiter 扩展。诀窍是您需要使用每个 class 测试实例生命周期模式,以便提早注册提供者以便 JUnit Jupiter 使用它。
以下是 JUnit 5 用户指南中 TestTemplateDemo
的修改版本。
测试通过 "as is",但您可以从 @Bean
声明中删除 baz
bean 的 //
以查看测试失败。
@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 Jupiter (JUnit 5) 中是否有一种方法可以将 Spring 组件注入 TestTemplateInvocationContextProvider
?
是的,如果您在为测试 class 加载的 Spring ApplicationContext
中将您的 TestTemplateInvocationContextProvider
注册为 bean,然后您可以让提供程序 @Autowired
到一个字段中,并使用 @RegisterExtension
注册为 JUnit Jupiter 扩展。诀窍是您需要使用每个 class 测试实例生命周期模式,以便提早注册提供者以便 JUnit Jupiter 使用它。
以下是 JUnit 5 用户指南中 TestTemplateDemo
的修改版本。
测试通过 "as is",但您可以从 @Bean
声明中删除 baz
bean 的 //
以查看测试失败。
@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;
}
});
}
};
}
}
}