【问题标题】:How to properly maintain data for Testcontainers in init script?如何在初始化脚本中正确维护 Testcontainers 的数据?
【发布时间】:2021-08-18 11:09:01
【问题描述】:

我正在使用 Testcontainers 加载一个 Dockerized 数据库,用于我的 Spring Boot 应用程序进行集成测试。我目前正在使用初始化脚本来加载所有数据:

CREATE TABLE public.table1 (
...
...
);

CREATE TABLE public.table2 (
...
...
);

这一切都很好。我也有自己的手动测试数据,我可以插入这些数据来测试不同的场景:

-- Data for pre-existing quiz
INSERT INTO public.table1 (id, prop1, prop2) values (1, 'a', 'b');
INSERT INTO public.table2 (id, prop1, prop2) values (1, 'c', 'd');
INSERT INTO public.table2 (id, prop1, prop2) values (2, 'e', 'f');

再次,一切正常,我正在使用 YAML 文件来读取模拟这些对象以用于我的测试

  table1s:
    first:
      id: 1
      prop1: a
      prop2: b
  table2s:
    first:
      id: 1
      prop1: c
      prop2: d
    second:
      id: 2
      prop1: e
      prop2: f

我可以将它们放入一个可以从 YAML 文件属性中读取的类中,以便用于我的测试类

public class Table1TestData {

    @Autowired
    private Environment env;

    private UUID id;
    private boolean prop1;
    private boolean prop2;

    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }

    public boolean getProp1() {
        return prop1;
    }

    public void setProp1(String trial) {
        this.prop1 = prop1;
    }

    ....

    public Table1TestData getFirstRowData(){
        Table1HelperFactory ret = new Table1HelperFactory();
        ret.setId(UUID.fromString(env.getProperty("table1s.first.id")));
        ret.setProp1(env.getProperty("table1s.first.id"));
        ....
        return ret;
    }
    ....

}

我在我的测试中使用这个助手作为一个自动装配的实体(特别是对于我的服务类):

public class Table1ServiceTest {

  @ClassRule
  public static PostgresContainer postgresContainer = PostgresContainer.getInstance();


  @Autowired
  Table1Service table1Service;

  @Autowired
  Table1TestData table1TestData;

  @Autowired
  MockMvc mockMvc;

  @Autowired
  ObjectMapper objectMapper;

  @BeforeAll
  private static void startup() {
    postgresContainer.start();
  }


  @Test
  @DisplayName("Table 1 Service Test")
  @Transactional
  public void findTable1ById() throws Exception {
    Table1TestData testData = table1TestData.getFirstRowData();
    Table1 table1 = table1Service.findTable1ById(testData.getId());
    assertNotNull(table1);
    assertEquals(table1.getId(), testData.getId());
    assertEquals(table1.prop1(), testData.prop1());
    ....

  }

}

但是,假设我必须将一个新列应用到 Table1(或任何表),然后我将新架构放入 init 脚本中。我现在必须手动转到这些插入语句中的每一个并放入一个带有值的新列(假设没有默认值),或者甚至说是否删除了一个列(即使它不一定影响类)。这最终变得很麻烦。

所以我的问题确实是,对于使用初始化脚本为容器化数据库填充测试数据的人来说,在不进行大量手动管理的情况下高效维护这些数据的最佳方法是什么?

【问题讨论】:

    标签: java spring docker integration-testing testcontainers


    【解决方案1】:

    我认为您可以利用 postgresql 的初始化脚本功能:只需将您的 sql 脚本放在 /docker-entrypoint-initdb.d 下(必要时创建目录),它将直接执行它们而无需任何编程工作。

    您可以在此处查看示例: https://github.com/gmunozfe/clustered-ejb-timers-kie-server/blob/master/src/test/java/org/kie/samples/integration/ClusteredEJBTimerSystemTest.java

    定义你的 postgresql 指向那个目录:

    .withFileSystemBind("etc/postgresql", "/docker-entrypoint-initdb.d",
                                                            BindMode.READ_ONLY)
    

    如果您希望每个测试使用不同的脚本,请查看这篇文章: https://www.baeldung.com/spring-boot-data-sql-and-schema-sql

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-21
      • 1970-01-01
      • 1970-01-01
      • 2019-09-15
      • 2021-10-05
      • 2019-04-09
      • 1970-01-01
      • 2020-03-19
      相关资源
      最近更新 更多