如何在init脚本中正确维护测试容器的数据



我正在使用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脚本中。我现在必须手动转到这些insert语句中的每一个,并放入一个带有值的新列(假设没有默认值(,甚至说是否删除了一列(即使它不一定会影响类(。这最终会很麻烦。

因此,我的问题是,对于那些使用init脚本为容器化数据库填充测试数据的人来说,在没有太多手动管理的情况下,有效维护这些数据的最佳方法是什么?

我认为您可以利用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

最新更新