【问题标题】:How to populate data in testcontainers?如何在测试容器中填充数据?
【发布时间】:2020-10-08 05:45:48
【问题描述】:

上下文:

我有一个非 Spring Boot 应用程序,我将其包装在 Spring Boot 中以测试功能。碰巧代码在测试中有一个内存数据库,我想针对不同的数据库进行测试以重现生产环境。我决定使用testcontainers 以保持所有现有测试不变。

问题:

我需要将数百万行加载到测试容器中。问题是如何在testcontainers 中填充数据库?我发现了一个类似的问题 -> How to populate testcontainers? 但我仍然无法在其中填充数据。

如何在testcontainers 中填充数据?

DatabaseTestInitalizer.java我用于实例化容器:

import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.testcontainers.containers.MSSQLServerContainer;

public class DatabaseTestInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    private MSSQLServerContainer mssqlServerContainer;

    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        mssqlServerContainer = new MSSQLServerContainer();
        mssqlServerContainer.start();

        // This is solution for 1.x.x Spring Boot framework
        // Article for migration from 1.x.x to 2.x.x Spring Boot https://stackoverflow.com/questions/54718995/appropriate-usage-of-testpropertyvalues-in-spring-boot-tests
        EnvironmentTestUtils.addEnvironment(configurableApplicationContext.getEnvironment(),
                "spring.datasource.url=" + mssqlServerContainer.getJdbcUrl(),
                "spring.datasource.username=" + mssqlServerContainer.getUsername(),
                "spring.datasource.password=" + mssqlServerContainer.getPassword()
        );
    }
}

【问题讨论】:

  • 您应该在测试类的“之前”块中手动填充它。或者你可以使用docker-entrypoint-initdb.d 机制。在此处查看“初始化新实例”部分:hub.docker.com/_/mysql
  • 您是使用 Flyway 来填充您的数据库架构,还是使用已经包含您架构的 MySQL Docker 映像?
  • @rieckpil 不,我真的不需要它的原因。在生产中,我只是从数据库中读取。我正在尝试创建一个测试以在测试中重现生产条件。 Flyway、Liquibase 或其他工具对于项目来说将是多余的和不必要的复杂化。我想我找到了解决方案.withInitScript,但它很慢。

标签: java spring-boot testcontainers


【解决方案1】:

经过更严格的搜索后,我可以使用 withInitScript 并将架构和数据定义到 init.sql,确保 db/init.sql 驻留在 test/resources 文件夹中。

它的工作原理如下:

public MSSQLServerContainer mssqlServerContainer = (MSSQLServerContainer) new MSSQLServerContainer()
            .withInitScript("db/init.sql")
            .withExposedPorts(1433);

在这种情况下,您不需要Flyway

【讨论】:

    【解决方案2】:

    你有两个选择:

    1. 从 dockerfile 链接创建容器:testcontainer dockerfileCustomize your MySQL Database in Docker
    2. 您可以使用flyway 等数据库迁移工具,数据库将自动填充

    【讨论】:

      【解决方案3】:

      当我使用类似的设置时,我实现了以下方法:

      1. 我已经在 Flyway 中管理了架构,它无论如何都与 Spring Boot 集成。所有的迁移都是与模式定义相关的迁移,并且没有对数据做任何事情。 我已将它们放在src/main/sesources/...(不是测试类路径)中——因为它们也与常规应用程序启动相关。

      2. 我为填充测试数据的测试创建了特殊迁移。这些迁移在我的模块的src/test/resources 下。 这些“测试”迁移的编写方式总是在常规迁移之后开始。

      3. 我已将 Flyway 配置为在测试之前启动,以便填充测试数据。

      毕竟,主要思想是将测试代码与数据生成解耦。

      它对我们有用 - 所以我可以推荐这种方法。

      话虽如此,如果你使用的是spring,还有其他方法:

      • 如果您使用 JPA,请在设置中“手动”添加数据。拨打这个电话 测试开始前的代码。
      • 使用@Sql 注释运行带有测试数据的脚本。总而言之,那里有很多选择,请阅读this tutorial了解更多信息

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-10
        • 1970-01-01
        • 1970-01-01
        • 2020-03-04
        • 1970-01-01
        • 2023-04-09
        • 1970-01-01
        • 2020-08-02
        相关资源
        最近更新 更多