Rei*_*der 5 java spring-boot spring-boot-test testcontainers
我正在使用带有 Spring Boot 的 TestContainers 为这样的存储库运行单元测试:
@Testcontainers
@ExtendWith(SpringExtension.class)
@ActiveProfiles("itest")
@SpringBootTest(classes = RouteTestingCheapRouteDetector.class)
@ContextConfiguration(initializers = AlwaysFailingRouteRepositoryShould.Initializer.class)
@TestExecutionListeners(listeners = DependencyInjectionTestExecutionListener.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Tag("docker")
@Tag("database")
class AlwaysFailingRouteRepositoryShould {
@SuppressWarnings("rawtypes")
@Container
private static final PostgreSQLContainer database =
new PostgreSQLContainer("postgres:9.6")
.withDatabaseName("database")
.withUsername("postgres")
.withPassword("postgres");
Run Code Online (Sandbox Code Playgroud)
但是现在我有 14 个这样的测试,每次运行测试时都会启动一个新的 Postgres 实例。是否可以在所有测试中重用同一个实例?该Singleton模式并没有帮助,因为每次测试开始一个新的应用。
我也试过testcontainers.reuse.enable=true在.testcontainers.properties和.withReuse(true),但是这并没有帮助。
rie*_*pil 16
@Container如果您想拥有可重用的容器,则不能使用 JUnit Jupiter 注释。此注释确保在每次测试后停止容器。
您需要的是单例容器方法,并使用 eg@BeforeAll来启动您的容器。即使您进行.start()了多个测试,如果您选择在.withReuse(true)容器定义和.testcontainers.properties主目录中的以下文件中使用可重用性,Testcontainers 也不会启动新容器:
testcontainers.reuse.enable=true
Run Code Online (Sandbox Code Playgroud)
一个简单的示例可能如下所示:
@SpringBootTest
public class SomeIT {
public static GenericContainer postgreSQLContainer = new PostgreSQLContainer().
withReuse(true);
@BeforeAll
public static void beforeAll() {
postgreSQLContainer.start();
}
@Test
public void test() {
}
}
Run Code Online (Sandbox Code Playgroud)
和另一个集成测试:
@SpringBootTest
public class SecondIT {
public static GenericContainer postgreSQLContainer = new PostgreSQLContainer().
withReuse(true);
@BeforeAll
public static void beforeAll() {
postgreSQLContainer.start();
}
@Test
public void secondTest() {
}
}
Run Code Online (Sandbox Code Playgroud)
我整理了一篇博客文章,详细解释了如何使用 Testcontainers 重用容器。
Ely*_*mov 12
接受的答案很好,但问题是您仍然必须为每个集成测试重复配置(创建、启动等)。如果配置更简单,代码行数更少,那就更好了。我认为更干净的版本将使用 JUnit 5 扩展。
这就是我解决问题的方法。下面的示例使用 MariaDB 容器,但该概念适用于所有人。
public class AppMariaDBContainer extends MariaDBContainer<AppMariaDBContainer> {
private static final String IMAGE_VERSION = "mariadb:10.5";
private static final String DATABASE_NAME = "my-db";
private static final String USERNAME = "user";
private static final String PASSWORD = "strong-password";
public static AppMariaDBContainer container = new AppMariaDBContainer()
.withDatabaseName(DATABASE_NAME)
.withUsername(USERNAME)
.withPassword(PASSWORD);
public AppMariaDBContainer() {
super(IMAGE_VERSION);
}
}
Run Code Online (Sandbox Code Playgroud)
DataSource属性的扩展类。如果需要的话运行迁移:public class DatabaseSetupExtension implements BeforeAllCallback {
@Override
public void beforeAll(ExtensionContext context) {
AppMariaDBContainer.container.start();
updateDataSourceProps(AppMariaDBContainer.container);
//migration logic here (if needed)
}
private void updateDataSourceProps(AppMariaDBContainer container) {
System.setProperty("spring.datasource.url", container.getJdbcUrl());
System.setProperty("spring.datasource.username", container.getUsername());
System.setProperty("spring.datasource.password", container.getPassword());
}
}
Run Code Online (Sandbox Code Playgroud)
@ExtendWith到您的测试类@SpringBootTest
@ExtendWith(DatabaseSetupExtension.class)
class ApplicationIntegrationTests {
@Test
void someTest() {
}
}
Run Code Online (Sandbox Code Playgroud)
另一个测试
@SpringBootTest
@ExtendWith(DatabaseSetupExtension.class)
class AnotherIntegrationTests {
@Test
void anotherTest() {
}
}
Run Code Online (Sandbox Code Playgroud)
brn*_*eto 10
如果您决定继续使用单例模式,请注意“通过 JDBC URL 方案启动的数据库容器”中的警告。我花了几个小时才注意到,即使我使用的是单例模式,总是会创建一个映射在不同端口上的附加容器。
jdbc:tc:postgresql:<image-tag>:///<databasename>总之,如果需要使用单例模式,请不要使用测试容器 JDBC(无主机)URI,例如。
使用单例容器或可重用容器都是可能的解决方案,但因为它们不将容器的生命周期限定在应用程序上下文的生命周期内,所以这两种方法都不太理想。
不过,可以通过使用 a 将容器的范围限定到应用程序上下文生命周期,ContextCustomizerFactory我已在博客文章中更详细地介绍了这一点。
在测试中使用:
@Slf4j
@SpringBootTest
@EnabledPostgresTestContainer
class DemoApplicationTest {
@Test
void contextLoads() {
log.info("Hello world");
}
}
Run Code Online (Sandbox Code Playgroud)
然后启用注释META-INF/spring.factories:
org.springframework.test.context.ContextCustomizerFactory=\
com.logarithmicwhale.demo.EnablePostgresTestContainerContextCustomizerFactory
Run Code Online (Sandbox Code Playgroud)
可以实现为:
org.springframework.test.context.ContextCustomizerFactory=\
com.logarithmicwhale.demo.EnablePostgresTestContainerContextCustomizerFactory
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5885 次 |
| 最近记录: |