Testcontainers: การทดสอบการผสานรวมกับฐานข้อมูลจริง
เริ่ม PostgreSQL ใน Docker ด้วย Testcontainers และเรียกใช้การทดสอบการผสานรวมกับฐานข้อมูลจริง
Testcontainers: การทดสอบการผสานรวมกับฐานข้อมูลจริง เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดจึงต้องใช้ Testcontainers
ฐานข้อมูล H2 ในหน่วยความจำไม่รองรับฟีเจอร์เฉพาะของ PostgreSQL เช่น JSON การค้นหาข้อความแบบเต็ม และ ON CONFLICT Testcontainers จะเริ่มคอนเทนเนอร์ Docker จริงระหว่างการทดสอบ ทำให้คุณได้ฐานข้อมูลที่เหมือนกับในสภาพแวดล้อมจริง
การเพิ่มการพึ่งพา Testcontainers
เพิ่ม BOM ของ Testcontainers และโมดูล PostgreSQL ลงในไฟล์บิลด์ของคุณ Spring Boot 3.1+ มีเวอร์ชัน Testcontainers ที่จัดการให้แล้ว
// build.gradle:
testImplementation "org.testcontainers:junit-jupiter"
testImplementation "org.testcontainers:postgresql"
// Optionally use Spring Boot Testcontainers support:
testImplementation "org.springframework.boot:spring-boot-testcontainers"@Testcontainers และ @Container
ใส่คำอธิบายประกอบ @Testcontainers ให้คลาสการทดสอบ และประกาศคอนเทนเนอร์เป็นฟิลด์ @Container แบบคงที่ JUnit 5 จะเริ่มและหยุดคอนเทนเนอร์ให้โดยอัตโนมัติ
@Testcontainers
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class UserRepositoryIntegrationTest {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine")
.withDatabaseName("testdb")
.withUsername("test")
.withPassword("test");
}การกำหนดค่า DataSource จากคอนเทนเนอร์
ใช้ @DynamicPropertySource เพื่อแทรกพอร์ตแบบไดนามิกและข้อมูลรับรองของคอนเทนเนอร์ลงในการกำหนดค่า DataSource ของ Spring
@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}ServiceConnection ของ Spring Boot 3.1
Spring Boot 3.1 ขึ้นไปจะกำหนดค่า DataSource จากบีนของ Testcontainers ที่มีแอตทริบิวต์ @Container และกำกับด้วย @ServiceConnection โดยอัตโนมัติ — ไม่จำเป็นต้องใช้ @DynamicPropertySource
@Bean
@ServiceConnection
static PostgreSQLContainer<?> postgresContainer() {
return new PostgreSQLContainer<>("postgres:16-alpine");
}รูปแบบคอนเทนเนอร์เดี่ยว
การเริ่มคอนเทนเนอร์ใหม่สำหรับแต่ละคลาสการทดสอบใช้เวลานาน โปรดใช้คอนเทนเนอร์เดียวร่วมกันในการทดสอบทั้งหมด โดยใช้ฟิลด์ static ร่วมกับ Startables.deepStart() หรือคลาสฐานนามธรรม
abstract class AbstractIntegrationTest {
@Container
static final PostgreSQLContainer<?> POSTGRES =
new PostgreSQLContainer<>("postgres:16-alpine").withReuse(true);
static { POSTGRES.start(); }
@DynamicPropertySource
static void props(DynamicPropertyRegistry r) {
r.add("spring.datasource.url", POSTGRES::getJdbcUrl);
r.add("spring.datasource.username", POSTGRES::getUsername);
r.add("spring.datasource.password", POSTGRES::getPassword);
}
}การทดสอบความสามารถเฉพาะของ PostgreSQL
Testcontainers ช่วยให้คุณทดสอบคอลัมน์ JSON, ตัวดำเนินการ JSONB, การค้นหาข้อความเต็ม และ ON CONFLICT DO UPDATE ได้ ซึ่งไม่สามารถทำได้ด้วย H2
@Test
void jsonb_search_works() {
// Insert row with JSONB column, then query
List<Event> logins = repo.findByType("login");
assertEquals(1, logins.size());
}หลายคอนเทนเนอร์: Compose
ใช้ DockerComposeContainer เพื่อเรียกใช้สแตกทั้งหมด (Postgres + Redis + Kafka) สำหรับการทดสอบการผสานรวมที่ต้องใช้บริการหลายรายการ
@Container
static DockerComposeContainer<?> compose = new DockerComposeContainer<>(
new File("src/test/resources/docker-compose.yml"))
.withExposedService("postgres", 5432)
.withExposedService("redis", 6379);Ryuk: การล้างข้อมูลอัตโนมัติ
Testcontainers ใช้คอนเทนเนอร์ Ryuk เพื่อหยุดและลบคอนเทนเนอร์โดยอัตโนมัติเมื่อ JVM สิ้นสุดการทำงาน แม้การทดสอบจะล้มเหลว จึงช่วยป้องกันคอนเทนเนอร์ตกค้าง
@SpringBootTest ร่วมกับ Testcontainers
ใช้ @SpringBootTest แทน @DataJpaTest เพื่อทดสอบสแตกของแอปพลิเคชันทั้งหมด (ตัวควบคุม บริการ ที่เก็บข้อมูล) กับคอนเทนเนอร์ Postgres จริง
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Testcontainers
class FullIntegrationTest extends AbstractIntegrationTest {
@LocalServerPort int port;
@Autowired TestRestTemplate rest;
@Test
void end_to_end_user_creation() {
ResponseEntity<UserDto> r = rest.postForEntity("/api/users", createReq(), UserDto.class);
assertEquals(HttpStatus.CREATED, r.getStatusCode());
}
}การแคชอิมเมจคอนเทนเนอร์
Testcontainers จะแคชอิมเมจ Docker ที่ดึงมาไว้ในเครื่อง โปรดดึงอิมเมจใน CI ก่อนเริ่มการทดสอบ (docker pull postgres:16-alpine) เพื่อหลีกเลี่ยงเวลาที่ต้องดาวน์โหลดระหว่างการทดสอบ
ตรวจสอบอย่างรวดเร็ว
แอตทริบิวต์ใดจะเชื่อมคอนเทนเนอร์ของ Testcontainers เข้ากับ DataSource ของ Spring โดยอัตโนมัติใน Spring Boot 3.1 ขึ้นไป
สรุปทบทวน
Testcontainers เรียกใช้คอนเทนเนอร์ Docker จริงสำหรับการทดสอบการผสานรวม ใช้ @Container + @DynamicPropertySource หรือ @ServiceConnection (Boot 3.1 ขึ้นไป) ใช้คอนเทนเนอร์ร่วมกันระหว่างการทดสอบด้วยรูปแบบคอนเทนเนอร์เดี่ยว และทดสอบความสามารถเฉพาะของ PostgreSQL ที่ H2 ไม่รองรับ
คำถามที่พบบ่อย
บทเรียน “Testcontainers: การทดสอบการผสานรวมกับฐานข้อมูลจริง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “Testcontainers: การทดสอบการผสานรวมกับฐานข้อมูลจริง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “Testcontainers: การทดสอบการผสานรวมกับฐานข้อมูลจริง”
เริ่ม PostgreSQL ใน Docker ด้วย Testcontainers และเรียกใช้การทดสอบการผสานรวมกับฐานข้อมูลจริง คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “Testcontainers: การทดสอบการผสานรวมกับฐานข้อมูลจริง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม
ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การทดสอบแบบกำหนดพารามิเตอร์ด้วย @CsvSource และ @MethodSource
- Mockito ขั้นสูง: ตัวจับอาร์กิวเมนต์และสายลับ
- ส่วนทดสอบ Spring Boot: @WebMvcTest และ @DataJpaTest
- Testcontainers: การทดสอบการผสานรวมกับฐานข้อมูลจริง