对于 SpringBoot 应用程序,是 spring 负责连接 bean。
在 JUnit 5 的情况下,Spring 管理的 Bean 必须注入到 JUnit 管理的测试类的实例中。幸运的是,JUnit 5 提供了一种通过 ParameterResolver 实现此目的的方法。
@SpringBootTest 注册 SpringExtension,除其他功能外,它还用作 ParameterResolver:
@Override
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
Parameter parameter = parameterContext.getParameter();
Executable executable = parameter.getDeclaringExecutable();
Class<?> testClass = extensionContext.getRequiredTestClass();
PropertyProvider junitPropertyProvider = propertyName ->
extensionContext.getConfigurationParameter(propertyName).orElse(null);
return (TestConstructorUtils.isAutowirableConstructor(executable, testClass, junitPropertyProvider) ||
ApplicationContext.class.isAssignableFrom(parameter.getType()) ||
supportsApplicationEvents(parameterContext) ||
ParameterResolutionDelegate.isAutowirable(parameter, parameterContext.getIndex()));
}
ParameterResolutionDelegate.isAutowirable依赖注解来判断是否可以从Spring的ApplicationContext中注入参数
public static boolean isAutowirable(Parameter parameter, int parameterIndex) {
Assert.notNull(parameter, "Parameter must not be null");
AnnotatedElement annotatedParameter = getEffectiveAnnotatedParameter(parameter, parameterIndex);
return (AnnotatedElementUtils.hasAnnotation(annotatedParameter, Autowired.class) ||
AnnotatedElementUtils.hasAnnotation(annotatedParameter, Qualifier.class) ||
AnnotatedElementUtils.hasAnnotation(annotatedParameter, Value.class));
}
其实如果省略@Autowired注解,JUnit会报错缺少ParameterResolver:
org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter [test.Mailer mailer] in constructor [public test.MailServiceTest(test.Mailer)].