Java @SpringBootTest+@以前
我有一个带有数据库和rabbitmq用法的小型spring启动应用程序。 所以我想用集成测试(H2+apacheqpid)进行测试 正如我的应用程序所期望的,数据库和mq Im使用@BeforeAll启动它:Java @SpringBootTest+@以前,java,spring,spring-boot,spring-test,junit5,Java,Spring,Spring Boot,Spring Test,Junit5,我有一个带有数据库和rabbitmq用法的小型spring启动应用程序。 所以我想用集成测试(H2+apacheqpid)进行测试 正如我的应用程序所期望的,数据库和mq Im使用@BeforeAll启动它: @BeforeAll public void before() { startMessageBroker(); startDatabase(); } 问题是我的web应用程序在@BeforeAll中定义的database/mq之前启动 org.springframewor
@BeforeAll
public void before() {
startMessageBroker();
startDatabase();
}
问题是我的web应用程序在@BeforeAll中定义的database/mq之前启动
org.springframework.test.context.junit.jupiter.SpringExtension:
public class SpringExtension implements BeforeAllCallback, AfterAllCallback, TestInstancePostProcessor,
BeforeEachCallback, AfterEachCallback, BeforeTestExecutionCallback, AfterTestExecutionCallback,
ParameterResolver {
// ...
@Override
public void beforeAll(ExtensionContext context) throws Exception {
getTestContextManager(context).beforeTestClass();
}
// ...
@Override
public void postProcessTestInstance(Object testInstance, ExtensionContext context) throws Exception {
getTestContextManager(context).prepareTestInstance(testInstance);
}
// ...
Web应用程序在postProcessTestInstance阶段启动,在BeforeAll中启动@BeforeAll方法
org.junit.platform.engine.support.hierarchy.hierarchycalTestExecutor:
private void execute(TestDescriptor testDescriptor, C parentContext, ExecutionTracker tracker) {
Node<C> node = asNode(testDescriptor);
tracker.markExecuted(testDescriptor);
C preparedContext;
try {
preparedContext = node.prepare(parentContext); // 1 <<<
SkipResult skipResult = node.shouldBeSkipped(preparedContext);
if (skipResult.isSkipped()) {
this.listener.executionSkipped(testDescriptor, skipResult.getReason().orElse("<unknown>"));
return;
}
}
catch (Throwable throwable) {
rethrowIfBlacklisted(throwable);
// We call executionStarted first to comply with the contract of EngineExecutionListener
this.listener.executionStarted(testDescriptor);
this.listener.executionFinished(testDescriptor, TestExecutionResult.failed(throwable));
return;
}
this.listener.executionStarted(testDescriptor);
TestExecutionResult result = singleTestExecutor.executeSafely(() -> {
C context = preparedContext;
try {
context = node.before(context); // 2 <<<
C contextForDynamicChildren = context;
context = node.execute(context, dynamicTestDescriptor -> {
this.listener.dynamicTestRegistered(dynamicTestDescriptor);
execute(dynamicTestDescriptor, contextForDynamicChildren, tracker);
});
C contextForStaticChildren = context;
// @formatter:off
testDescriptor.getChildren().stream()
.filter(child -> !tracker.wasAlreadyExecuted(child))
.forEach(child -> execute(child, contextForStaticChildren, tracker));
// @formatter:on
}
finally {
node.after(context);
}
});
this.listener.executionFinished(testDescriptor, result);
}
private void execute(TestDescriptor TestDescriptor、C parentContext、ExecutionTracker跟踪程序){
Node=asNode(testDescriptor);
markExecuted(testDescriptor);
C准备上下文;
试一试{
preparedContext=node.prepare(parentContext);//1{
C context=preparedContext;
试一试{
context=node.before(context);//2!tracker.wasAlreadyExecuted(子)
.forEach(child->execute(child、contextForStaticChildren、tracker));
//@formatter:on
}
最后{
node.after(上下文);
}
});
this.listener.executionFinished(testDescriptor,result);
}
参见第1点和第2点。执行“准备”和“之前”
我不确定是junit、SpringExtension的问题还是我做错了什么。
有什么建议吗
junit jupiter:5.0.1
弹簧试验:5.0.0.0释放
弹簧启动测试:1.5.8.1释放
JUnit5[@BeforeAll]注释替换了JUnit4中的注释。 它用于表示在当前测试类中的所有测试之前应该执行带注释的方法 @在静态方法中应使用BeforeAll 更多阅读:
我认为这是设计上的。尝试将Bean后处理器/上下文初始值设定项添加到init/start-your-DB/rabbitMQ..是否有任何理由在测试类中启动DB和message broker?在我看来,这是设计上的错误。它们都应该与应用程序上下文一起启动,因为它们是基础结构的一部分e 您的测试不负责设置您的基础架构! IMHO,一个更好的做事方式是:
- 在maven+中将H2依赖项与
测试
作用域一起使用,以在应用程序上下文启动时启动H2的方式配置启动器
- 在应用程序启动时启动apache qpid(最好是嵌入式的)
- 在@Before中,只需确保在运行测试用例之前清理好内容
private void execute(TestDescriptor testDescriptor, C parentContext, ExecutionTracker tracker) {
Node<C> node = asNode(testDescriptor);
tracker.markExecuted(testDescriptor);
C preparedContext;
try {
preparedContext = node.prepare(parentContext); // 1 <<<
SkipResult skipResult = node.shouldBeSkipped(preparedContext);
if (skipResult.isSkipped()) {
this.listener.executionSkipped(testDescriptor, skipResult.getReason().orElse("<unknown>"));
return;
}
}
catch (Throwable throwable) {
rethrowIfBlacklisted(throwable);
// We call executionStarted first to comply with the contract of EngineExecutionListener
this.listener.executionStarted(testDescriptor);
this.listener.executionFinished(testDescriptor, TestExecutionResult.failed(throwable));
return;
}
this.listener.executionStarted(testDescriptor);
TestExecutionResult result = singleTestExecutor.executeSafely(() -> {
C context = preparedContext;
try {
context = node.before(context); // 2 <<<
C contextForDynamicChildren = context;
context = node.execute(context, dynamicTestDescriptor -> {
this.listener.dynamicTestRegistered(dynamicTestDescriptor);
execute(dynamicTestDescriptor, contextForDynamicChildren, tracker);
});
C contextForStaticChildren = context;
// @formatter:off
testDescriptor.getChildren().stream()
.filter(child -> !tracker.wasAlreadyExecuted(child))
.forEach(child -> execute(child, contextForStaticChildren, tracker));
// @formatter:on
}
finally {
node.after(context);
}
});
this.listener.executionFinished(testDescriptor, result);
}