当前位置: 首页 > 知识库问答 >
问题:

@SpringBootTest@之前

百里芷阳
2023-03-14

我有一个带有数据库和rabbitmq用法的小型spring boot应用程序。所以我想用集成测试(H2 apache qpid)进行测试。

@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = TestSpringConfig.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)

正如我的应用程序期望数据库和mq Im使用@BeforeAll启动它一样:

@BeforeAll
public void before() {
    startMessageBroker();
    startDatabase();
}

问题是,我的web应用程序在@BeforeAll中定义的数据库/mq之前启动。

组织。springframework。测验上下文朱尼特。木星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方法中启动。

组织。朱尼特。站台发动机支持等级制的层次测试执行器:

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);
}

参见第1点和第2点。执行“prepare”和“before”。

我不确定是junit、SpringExtension的问题,还是我做错了什么。有什么建议吗?

Junit-jupiter:5.0.1

Spring试验:5.0.0。发布

Spring启动测试:1.5.8。发布

共有3个答案

谷梁淇
2023-03-14

有什么理由在测试类中启动数据库和消息代理吗?在我看来,这在设计上是错误的。它们都应该与您的应用程序上下文一起启动,因为它们是您的基础设施的一部分。

设置您的基础设施不是您的测试的责任!

IMHO,更好的做法是:

  • 将H2依赖与maven中的test范围一起使用配置启动器,以在应用程序上下文启动时启动H2的方式
  • 在应用程序启动时启动apache qpid(最好嵌入
  • 在@之前只是确保在运行测试用例之前清理东西
归俊
2023-03-14

我认为这是故意的。尝试将Bean后处理器/上下文初始值设定项添加到初始化/启动DB/rabbitMQ。。

张炳
2023-03-14

结账https://www.testcontainers.org/作为JUnit测试的一部分,它提供了与JUnit的集成,以启动RabbitMQ和docker容器中的数据库。这使得集成测试非常现实,因为您使用的数据库和消息队列版本与生产中使用的版本相同。

 类似资料:
  • 在单元测试中, 你能给我解释一下每一个的用例吗?

  • 我已经创建了一个控制器,它实际上在我的TestCase中以错误告终。有很少其他控制器,我做了相同的方式,那里的测试工作。目前我正在寻找一个解决方案,但我被困了几个小时。 以下testcase失败,因为它导致http错误500而不是200 下面是正在测试的方法。我已经调试过了,看起来不错。实体已经被创建,而且到了ResponseEntity应该返回ok的时候,实体就在它的主体中。我还计算了这个返回r

  • 我有一个简单的健康控制器定义如下: 以及测试它的测试类: 运行测试时,我得到以下错误: 下面是AppConfiguration。java与主spring boot app类在同一个包中定义: 主要类别: 如果我将测试类中的注释修改如下,测试通过: 我错过了什么?

  • 我有以下测试: 你能给出解决这个问题的最佳方法吗?我在MapStruct 1.3.1上。决赛

  • 我有一个docker DB安装方法,它目前位于中。目前,构造如下 有多个测试类都扩展了这个测试超类,每个测试类将构造一个容器,并在完成后将其删除。因此,maven需要花费大量时间来管理docker。(创建和删除) 我的问题是, 我可能想要实现的理想情况是,这个容器创建 我有一些不完整的想法: 在SpringBoot主类中添加构造函数触发器,如果它是由Test启动的,则运行Docker容器构造函数。