1. 概述
本文将介绍 Testcontainers 的 JDBC 支持功能,并对比两种在测试中启动 Docker 容器的方式:
- 手动管理容器生命周期:通过代码直接控制容器启动/停止
- JDBC 驱动自动管理:通过配置属性自动启动容器
我们将从手动管理开始,逐步展示如何通过 JDBC 支持简化配置。
2. 手动管理容器生命周期
Testcontainers 是一个轻量级测试框架,提供可销毁的 Docker 容器。使用它可以:
✅ 避免使用 Mock
✅ 测试真实服务(数据库、消息队列等)
✅ 消除外部依赖
2.1 基础配置
以 PostgreSQL 测试为例,首先添加依赖:
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.19.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<version>1.19.8</version>
<scope>test</scope>
</dependency>
2.2 容器生命周期管理
手动管理需要完成四个步骤:
- 创建容器对象
- 测试前启动容器
- 配置应用连接参数
- 测试后销毁容器
使用 JUnit5 和 Spring Boot 实现:
@SpringBootTest
class FullTestcontainersLifecycleLiveTest {
static PostgreSQLContainer postgres = new PostgreSQLContainer("postgres:16-alpine")
.withDatabaseName("test-db");
@BeforeAll
static void beforeAll() {
postgres.start();
}
@DynamicPropertySource
static void setProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}
@AfterAll
static void afterAll() {
postgres.stop();
}
// tests
}
⚠️ 虽然这种方式提供了细粒度控制,但配置繁琐。好在 Testcontainers 提供了更简单的 JDBC 支持方案。
3. 使用 Testcontainers JDBC 驱动
核心优势:通过特殊 JDBC URL 自动启动容器,无需手动管理生命周期。
3.1 配置方式
JDBC URL 格式:jdbc:tc:<docker-image-name>:<image-tag>///database-name
示例配置(YAML):
spring.datasource.url: jdbc:tc:postgresql:16-alpine:///test-db
3.2 测试类实现
直接通过注解配置,无需容器管理代码:
@SpringBootTest(properties =
"spring.datasource.url: jdbc:tc:postgresql:16-alpine:///test-db"
)
class CustomTestcontainersDriverLiveTest {
@Autowired
HobbitRepository theShire;
@Test
void whenCallingSave_thenEntityIsPersistedToDb() {
theShire.save(new Hobbit("Frodo Baggins"));
assertThat(theShire.findAll())
.hasSize(1).first()
.extracting(Hobbit::getName)
.isEqualTo("Frodo Baggins");
}
}
✅ 关键优势:Testcontainers 自动处理容器生命周期,开发者只需关注业务逻辑测试。
4. 总结
方案 | 优点 | 缺点 |
---|---|---|
手动管理 | 灵活控制生命周期,可深度定制 | 代码冗余,配置复杂 |
JDBC 驱动 | 一行配置搞定,零样板代码 | 定制能力有限 |
推荐场景:
- 需要特殊容器配置 → 手动管理
- 标准数据库测试 → JDBC 驱动(简单粗暴高效)
完整示例代码见 GitHub 仓库