0Pricing
Java Academy · Lekcja

Testcontainers: integracyjne testy z rzeczywistą bazą danych

Proszę uruchamiać PostgreSQL w Dockerze za pomocą Testcontainers i wykonywać testy integracyjne na rzeczywistej bazie danych.

Testcontainers: integracyjne testy z rzeczywistą bazą danych to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Java Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Java Academy zawiera 4 lekcji w sumie.

Dlaczego warto używać Testcontainers?

Wbudowane bazy danych H2 nie obsługują funkcji specyficznych dla PostgreSQL (JSON, wyszukiwanie pełnotekstowe, ON CONFLICT). Testcontainers uruchamia podczas testów rzeczywiste kontenery Docker, zapewniając bazę danych identyczną z produkcyjną.

Dodawanie zależności Testcontainers

Dodaj BOM Testcontainers oraz moduł PostgreSQL do pliku konfiguracji kompilacji. Spring Boot 3.1+ zawiera zarządzaną wersję 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 i @Container

Oznacz klasę testową adnotacją @Testcontainers i zadeklaruj kontener jako statyczne pole @Container. JUnit 5 automatycznie go uruchomi i zatrzyma.

@Testcontainers
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class UserRepositoryIntegrationTest {
    @Container
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine")
        .withDatabaseName("testdb")
        .withUsername("test")
        .withPassword("test");
}

Konfigurowanie DataSource na podstawie kontenera

Użyj @DynamicPropertySource, aby wstrzyknąć dynamiczny port kontenera i dane uwierzytelniające do konfiguracji 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 w Spring Boot 3.1

Spring Boot 3.1+ automatycznie konfiguruje DataSource na podstawie komponentu Testcontainers @Container oznaczonego adnotacją @ServiceConnection — nie ma potrzeby używania @DynamicPropertySource.

@Bean
@ServiceConnection
static PostgreSQLContainer<?> postgresContainer() {
    return new PostgreSQLContainer<>("postgres:16-alpine");
}

Wzorzec singletona kontenera

Uruchamianie kontenera dla każdej klasy testowej jest powolne. Jeden kontener można współdzielić między wszystkimi testami, używając pola statycznego z Startables.deepStart() lub abstrakcyjnej klasy bazowej.

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);
    }
}

Testowanie funkcji specyficznych dla PostgreSQL

Za pomocą Testcontainers można testować kolumny JSON, operatory JSONB, wyszukiwanie pełnotekstowe oraz ON CONFLICT DO UPDATE — czego nie da się zrobić z H2.

@Test
void jsonb_search_works() {
    // Insert row with JSONB column, then query
    List<Event> logins = repo.findByType("login");
    assertEquals(1, logins.size());
}

Wiele kontenerów: Compose

DockerComposeContainer służy do uruchamiania pełnego stosu (Postgres + Redis + Kafka) na potrzeby testów integracyjnych wymagających wielu usług.

@Container
static DockerComposeContainer<?> compose = new DockerComposeContainer<>(
    new File("src/test/resources/docker-compose.yml"))
    .withExposedService("postgres", 5432)
    .withExposedService("redis", 6379);

Ryuk: automatyczne czyszczenie

Testcontainers korzysta z kontenera Ryuk, który automatycznie zatrzymuje i usuwa kontenery po zakończeniu działania JVM — nawet w przypadku niepowodzenia testu, zapobiegając pozostawianiu osieroconych kontenerów.

@SpringBootTest z Testcontainers

Należy użyć @SpringBootTest zamiast @DataJpaTest, aby przetestować cały stos aplikacji (kontrolery, usługi, repozytoria) z użyciem rzeczywistego kontenera 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());
    }
}

Buforowanie obrazów kontenerów

Testcontainers lokalnie buforuje pobrane obrazy Dockera. Obrazy należy pobrać w CI przed uruchomieniem testów (docker pull postgres:16-alpine), aby uniknąć dodatkowego czasu pobierania podczas wykonywania testów.

Szybkie sprawdzenie

Która adnotacja automatycznie konfiguruje DataSource Springa na podstawie kontenera Testcontainers w Spring Boot 3.1+?

Podsumowanie

Testcontainers uruchamia rzeczywiste kontenery Dockera na potrzeby testów integracyjnych. Należy używać @Container + @DynamicPropertySource lub @ServiceConnection (Boot 3.1+). Kontenery można współdzielić między testami za pomocą wzorca singletona. Można też testować funkcje specyficzne dla PostgreSQL, których nie da się przetestować z H2.

Często zadawane pytania

Czy lekcja „Testcontainers: integracyjne testy z rzeczywistą bazą danych” jest bezpłatna?

Tak — pełny tekst „Testcontainers: integracyjne testy z rzeczywistą bazą danych” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Java Academy, przejdź na CoddyKit PRO. Kurs Java Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Testcontainers: integracyjne testy z rzeczywistą bazą danych”?

Proszę uruchamiać PostgreSQL w Dockerze za pomocą Testcontainers i wykonywać testy integracyjne na rzeczywistej bazie danych. Ćwiczysz Java Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Java Academy?

Nie wymagamy żadnego doświadczenia. Java Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Testcontainers: integracyjne testy z rzeczywistą bazą danych”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Java Academy?

Tak. Każda lekcja Java Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Testy parametryzowane za pomocą @CsvSource i @MethodSource
  2. Mockito zaawansowane: przechwytywanie argumentów i szpiegi
  3. Wycinanie testów Spring Boot: @WebMvcTest i @DataJpaTest
  4. Testcontainers: integracyjne testy z rzeczywistą bazą danych
← Powrót do Java Academy