问题描述
我进行了很多集成测试,并且设置了 liquibase 以便可以初始化数据库。但是每个测试类都会初始化一个新的初始化。在这种情况下,重复数据错误是不可避免的。我找到了一些避免这种情况的建议,但遇到了问题。
- changelog-1.xml
<databaseChangeLog
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd">
<changeSet author="n" context="test" id="1" runOnChange="false">
<sqlFile encoding="utf8" endDelimiter="\nGO" path="classpath:dump.sql" relativetochangelogFile="false"/>
</changeSet>
</databaseChangeLog>
- 大师
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd">
<include file="xml/changelog-1.xml" relativetochangelogFile="true"/>
</databaseChangeLog>
我也写了一个配置类。
在包中:
- liquibase.ext
public class CleanUpDatabaseTestExecutionListener extends AbstractTestExecutionListener {
@Autowired
SpringLiquibase liquibase;
@Override
public int getorder() {
return Ordered.HIGHEST_PRECEDENCE;
}
@Override
public void afterTestClass(TestContext testContext) throws Exception {
testContext.getApplicationContext()
.getAutowireCapablebeanfactory()
.autowireBean(this);
liquibase.afterPropertiesSet();
}
}
- 上下文
@Slf4j
@SpringBoottest(webEnvironment = WebEnvironment.RANDOM_PORT)
@TestExecutionListeners(listeners = {
DependencyInjectionTestExecutionListener.class,TransactionalTestExecutionListener.class,CleanUpDatabaseTestExecutionListener.class,})
public abstract class AbstractTestcontainers extends ContainerConfig {
我收到一个错误:liquibase.exception.MigrationFailedException: 更改集迁移失败 db/changelog/test/liquibase-initdb.xml::1::n: 原因:liquibase.exception.DatabaseException:错误:类型“calc_types”已经存在[失败的sql:(0)-- -- Postgresql 数据库转储
spring.liquibase.drop-first=true - 它不起作用。
也许谁知道我该如何纠正?
解决方法
此刻,我做到了
@Slf4j
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public abstract class AbstractTestcontainers extends ContainerConfig{
@DynamicPropertySource
private static void dynamicProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url",postgreSQLContainer::getJdbcUrl);
registry.add("spring.datasource.username",postgreSQLContainer::getUsername);
registry.add("spring.datasource.password",postgreSQLContainer::getPassword);
}
}
我不得不放弃:
@DirtiesContext(classMode = ClassMode.BEFORE_CLASS)
public abstract class ContainerConfig {
protected static final PostgreSQLContainer postgreSQLContainer;
static {
DockerImageName postgres = DockerImageName.parse("postgres:11.7");
postgreSQLContainer = (PostgreSQLContainer) new PostgreSQLContainer(postgres)
.withDatabaseName("test")
.withPassword("root")
.withUsername("root")
.withReuse(true);
postgreSQLContainer.start();
}
}
我不得不离开一些课程
@Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD,scripts = "classpath:createUsers.sql")
public class SomeClassRestTest extends AbstractTestcontainers {
清除表格并用新数据填充它们。
Liquibase 配置运行一次,至少我没有看到更多的冲突。由于我们创建了一个引发上下文的类,并且所有其他集成测试都使用此上下文执行。当然,测试类本身是错误的,有必要使用@AfterClass 或@AfterMethod 注释从数据库中清除数据。尽管如此,现在大约 300 个测试的执行量减少了大约 4 倍。
如果这个问题有其他解决方案,请留言。