首页 > 解决方案 > 如何在@SpringBootTest 之前添加设置并且只运行一次?

问题描述

我有一个 docker DB 设置方法,目前位于@BeforeAll. 目前,构造如下

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public DockerConstructorTest{
  @BeforeAll
  public static void setup(){
    ...
    CreateContainer
    ...
  }

  @AfterAll
  public static void done(){
    ...
    Stop & Remove Container
    ...
  }
}

有多个测试类都扩展了这个 Test 超类,每个测试类将构建一个容器并在完成后将其删除。因此,maven 管理 docker 会耗费大量时间。(创建和删除)

我的问题是whether there's better way to deal with it

我可能想要实现的理想情况是,这个容器创建和删除只在@SpringBootTest 启动之前运行一次,它将与所有测试类共享。同时,它也不会阻止其他开发人员为某些角落场景创建新容器。

我有一些不完整的想法:

  1. 在 SpringBoot 主类中添加 Constructor 触发器,如果​​是 Test 启动的,则运行 Docker 容器构造函数。但这也意味着我在 Main Class 中添加了一些测试相关的代码,使它们耦合在一起。个人讨厌这种情况发生
  2. 覆盖 SpringBootTest。压倒我是否应该这样做的错误。

请分享您的绝妙想法,如果它可以解决此问题或部分解决此问题,我将不胜感激。

标签: javaspring-bootjunitspring-boot-testdocker-java

解决方案


不确定您的情况到底是什么,但是,我建议您将 TestContainers 与 Spring Boot 一起使用,您可以开箱即用地使用许多可配置的容器。此外,它们解决了您的问题,您可以拥有 Singleton 容器。 https://github.com/testcontainers/testcontainers-spring-boot

这里有一些关于如何将它用于多个类(单例容器)的参考, https://www.testcontainers.org/test_framework_integration/manual_lifecycle_control/

在我们的用例中,我们使用 Spock/Groovy 和 TestContainers,我们的基类大致如下所示。

@SpringBootTest(classes = DonkeyApplication.class)
class AbstractSpringSpec extends Specification {
    @Shared
    Closure cleanupClosure
    @Shared
    boolean setupSpecDone = false

    def setup() {
        if (!setupSpecDone) {
            setupSpecWithSpring()
            setupSpecDone = true
        }
        cleanupClosure = this.&cleanupSpecWithSpring
    }

    def cleanupSpec() {
        cleanupClosure?.run()
    }

    def setupSpecWithSpring() {
        // override this if Spring Beans are needed in setupSpec
    }

    def cleanupSpecWithSpring() {
        // override this if Spring Beans are needed in cleanupSpec
    }
}

参考

小参考spock在清理或设置上做了什么: 在此处输入图像描述

希望这个凌乱的答案能给你的问题一些答案!


推荐阅读