測試容器 JDBC 支援
1. 概述
在這篇短文中,我們將了解 Testcontainers JDBC 支持,並將比較在測試中啟動 Docker 容器的兩種不同方法。
最初,我們將以程式方式管理測試容器的生命週期。之後,我們將利用框架的 JDBC 支持,透過單一配置屬性來簡化此設定。
2. 手動管理測試容器生命週期
Testcontainers 是一個提供輕量級一次性 Docker 容器用於測試的框架。我們可以使用它來針對真實服務(例如資料庫、訊息佇列或 Web 服務)執行測試,而無需模擬或外部相依性。
假設我們想要使用 Testcontainers 來驗證與 PostgreSQL 資料庫的交互作用。首先,我們將testcontainers依賴項加入pom.xml
中:
<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>
之後,我們必須按照幾個簡單的步驟來管理容器的生命週期:
- 建立容器對象
- 在所有測試之前啟動容器
- 配置應用程式以與容器連接
- 測試結束時停止容器
我們可以使用 JUnit5 和 Spring Boot 註解(例如@BeforeAll, @AfterAll,
和@DynamicPropertyRegistry
)來自行實現這些步驟:
@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
}
儘管該解決方案允許我們自訂特定的生命週期階段,但它需要複雜的設定。幸運的是,該框架提供了一種方便的解決方案來啟動容器並使用最少的配置透過 JDBC 與它們進行通訊。
3. 使用 Testcontainers JDBC 驅動程式
當我們使用測試容器的 JDBC 驅動程式時,測試容器將自動啟動託管我們資料庫的 Docker 容器。為此,我們需要更新測試執行的 JDBC URL,並使用模式: “jdbc:tc:<docker-image-name>:<image-tag>:///<database-name>”
。
讓我們在測試中使用此語法來更新spring.datasource.url
:
spring.datasource.url: jdbc:tc:postgresql:16-alpine:///test-db
不用說,這個屬性可以在專用的設定檔中定義,也可以透過@SpringBootTest
註解在測試本身中定義:
@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");
}
}
我們可以注意到,我們不再需要手動處理 PostgreSQL 容器的生命週期。測試容器可以處理這種複雜性,使我們能夠專注於手邊的測試。
4。
在這個簡短的教學中,我們探索了啟動 Docker 容器並透過 JDBC 連接到它的不同方法。首先,我們手動建立並啟動容器,並將其與應用程式連接。該解決方案需要更多樣板程式碼,但允許特定的自訂。另一方面,當我們使用 Testcontainers 中的自訂 JDBC 驅動程式時,我們只需一行配置即可實現相同的設定。
與往常一樣,本文中使用的完整程式碼可以在 GitHub 上找到。