在没有Testcontainers的情况下运行SpringBootTest上下文启动



我有两个父测试类:

@SpringBootTest(properties = {
"spring.datasource.url=jdbc:tc:mysql:8.0.25:///my_test_db?TC_INITSCRIPT=db/init_mysql.sql",
"spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver"
})
@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL)
public abstract class UserApplicationIntegrationTest {
}

@SpringBootTest
@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL)
public abstract class UserApplicationTest {
}

这个想法是让各种测试类来扩展这些类。那些需要模拟MySQL数据库的数据库将扩展UserApplicationIntegrationTest。那些不需要DB连接但需要Spring上下文的应用程序将扩展UserApplicationTest。

在没有UserApplicationIntegrationTest的情况下,所有扩展UserApplicationTest的测试类都能很好地工作,包括使用Mockito框架。不幸的是,当我介绍UserApplicationIntegrationTest及其子测试(它们与停靠数据库实例完美配合(时,这些测试开始失败,因为它们突然需要数据源。

Caused by: org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class

如果我尝试在应用程序属性或父类的注释中排除数据源自动配置,那么testcontainers测试(那些扩展UserApplicationIntegrationTest的测试(就会开始失败,因为Spring上下文有问题,并且在这些测试中无法再自动连接bean。

在我意识到这一点之前,我已经陷入了一个兔子洞,试图进行以前项目中遇到过的混乱的排除/添加,这只会导致问题的进一步发展。

本质上,我希望在我的项目中共存3种类型的测试:

  1. 没有Spring上下文的单元测试
  2. 使用Spring上下文进行单元测试(包括大量模拟但仍然支持自动布线/构造函数注入(
  3. 使用Spring上下文进行集成测试,该上下文启动测试容器,并允许我测试DB交互(以及可能到来的端到端测试(

我想避免为所有Spring上下文测试启动testcontainer(这将非常好地"工作",并且在构建过程中只包括1个docker延迟(的最初原因是,在开发过程中,每次在本地运行单独的Spring上下文测试时,都要等待mysql连接到dockerised实例,这让我很恼火。

有没有一种整洁的方法来实现这一点,或者有一种更好的方法来引导需求?

提前谢谢。

希望我理解得对,我所做的是实现一个抽象的TestContainer测试类:

package de.dwosch.it;
@ActiveProfiles("test")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ContextConfiguration(initializers = AbstractPostgreSQLTestContainerIT.Initializer.class)
@Testcontainers
public abstract class AbstractPostgreSQLTestContainerIT {
private static final String POSTGRES_VERSION = "postgres:11.1";
public static PostgreSQLContainer database;

static {
database = new PostgreSQLContainer(POSTGRES_VERSION);
database.start();
}

static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(
configurableApplicationContext,
"spring.datasource.url=" + database.getJdbcUrl(),
"spring.datasource.username=" + database.getUsername(),
"spring.datasource.password=" + database.getPassword()
);
}
}
}

然后,我只需通过这个抽象类来扩展我的测试类,它将启动一个测试容器和整个spring上下文,以便更好地分离

class MyAwesomeControllerIT extends AbstractPostgreSQLTestContainerIT { }

最新更新