我注意到,当我进行 Spring Boot 测试时,上下文无法初始化,横幅会打印两次,我决定研究一下原因。
// spring-boot-test-autoconfigure 2.3.7.RELEASE
public class SpringBootDependencyInjectionTestExecutionListener extends DependencyInjectionTestExecutionListener {
@Override
public void prepareTestInstance(TestContext testContext) throws Exception {
try {
super.prepareTestInstance(testContext);
}
catch (Exception ex) {
outputConditionEvaluationReport(testContext);
throw ex;
}
}
.....
}
当初始化期间抛出异常时,outputConditionEvaluationReport(testContext)
会调用 ,最终导致上下文在 内部被第二次初始化DefaultCacheAwareContextLoaderDelegate::loadContext
。
这比错误更令人讨厌,因为它只发生在测试代码中;成本只是开发人员的时间和构建资源。
在这种特殊情况下,我想快速失败,所以我抛出一个异常,因为我知道稍后会发生不好的事情。我试图防止经验不足的开发人员使用预期生命周期之外的资源。在测试过程中,我们会在早期生命周期阶段自动创建外部资源,这些资源只能在后期阶段以及应用程序启动后访问。如果开发人员违反此规则,并尝试在 bean 构造期间或早期生命周期中访问资源,我可以检测到它,并抛出 IlligealStateException。如果我不这样做,我稍后会从资源 Api 收到异常,并且如果初级开发人员从 HttpClient 收到 404/500 错误,他们可能很难确定他们违反了资源生命周期。
一种可能的解决方案是拥有一个AbortTestContextInitializationException
, 如果您认为TestContext
继续执行没有意义,并且尝试生成ConditionEvaluationReport
.理想情况下,初始化的失败将被缓存,因此使用相同上下文的其他测试将立即失败,而不是使用构建资源,尝试为每个测试创建两次上下文。