首页 > 解决方案 > liquibase.exception.MigrationFailedException:更改集迁移失败 - 所有集成测试的数据库初始化期间出错

问题描述

我有很多集成测试,我已经设置了 liquibase 以便可以初始化数据库。但是每个测试类都会初始化一个新的初始化。在这种情况下,重复数据错误是不可避免的。我找到了一些避免这种情况的建议,但遇到了问题。

<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>

我还写了一个配置类。

在包装中:

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 - 它不起作用。

也许谁知道我该如何纠正这个?

标签: javaliquibasespring-boot-test

解决方案


此刻,我这样做了

@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 倍。

如果有其他解决此问题的方法,请写信。


推荐阅读