0Pricing
Java Academy · Lezione

Testcontainers: test di integrazione con database reali

Avvii PostgreSQL in Docker con Testcontainers ed esegua test di integrazione su un database reale.

Testcontainers: test di integrazione con database reali è una lezione Java Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Java Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Java Academy include 4 lezioni in totale.

Perché utilizzare Testcontainers?

I database in memoria H2 non supportano le funzionalità specifiche di PostgreSQL, come JSON, la ricerca full-text e ON CONFLICT. Testcontainers avvia veri container Docker durante i test, fornendo un database identico a quello di produzione.

Aggiunta della dipendenza Testcontainers

Aggiunga la BOM di Testcontainers e il modulo PostgreSQL al file di build. Spring Boot 3.1+ include una versione di Testcontainers gestita.

// 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 e @Container

Annoti la classe di test con @Testcontainers e dichiari il container come campo statico @Container. JUnit 5 lo avvia e lo arresta automaticamente.

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

Configurazione di DataSource dal container

Utilizzi @DynamicPropertySource per iniettare la porta dinamica e le credenziali del container nella configurazione di DataSource di 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);
}

Spring Boot 3.1 ServiceConnection

Spring Boot 3.1+ configura automaticamente il DataSource a partire da un bean @Container di Testcontainers annotato con @ServiceConnection: non è necessario usare @DynamicPropertySource.

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

Pattern del container singleton

Avviare un container per ogni classe di test è lento. Condivida un unico container tra tutti i test usando un campo statico con Startables.deepStart() oppure una classe base astratta.

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

Test delle funzionalità specifiche di PostgreSQL

Con Testcontainers può testare le colonne JSON, gli operatori JSONB, la ricerca full-text e ON CONFLICT DO UPDATE: con H2 è impossibile.

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

Più container: Compose

Utilizzi DockerComposeContainer per eseguire uno stack completo (Postgres + Redis + Kafka) per i test di integrazione che richiedono più servizi.

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

Ryuk: pulizia automatica

Testcontainers utilizza un container Ryuk per arrestare e rimuovere automaticamente i container quando termina la JVM, anche se un test fallisce, evitando che rimangano container inutilizzati.

@SpringBootTest con Testcontainers

Utilizzi @SpringBootTest invece di @DataJpaTest per testare l'intero stack dell'applicazione (controller, servizi, repository) con un container Postgres reale.

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

Memorizzazione nella cache delle immagini dei container

Testcontainers memorizza nella cache locale le immagini Docker scaricate. Esegua il pull delle immagini in CI prima dei test (docker pull postgres:16-alpine) per evitare i tempi di download durante l'esecuzione.

Verifica rapida

Quale annotazione collega automaticamente un container Testcontainers al DataSource di Spring in Spring Boot 3.1+?

Riepilogo

Testcontainers esegue veri container Docker per i test di integrazione. Utilizzi @Container + @DynamicPropertySource oppure @ServiceConnection (Boot 3.1+). Condivida i container tra i test usando il pattern singleton. Testi le funzionalità specifiche di PostgreSQL che sono impossibili con H2.

Domande Frequenti

La lezione «Testcontainers: test di integrazione con database reali» è gratuita?

Sì — il testo completo di «Testcontainers: test di integrazione con database reali» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Java Academy, passa a CoddyKit PRO. Il corso Java Academy include 4 lezioni in totale.

Cosa imparerò in «Testcontainers: test di integrazione con database reali»?

Avvii PostgreSQL in Docker con Testcontainers ed esegua test di integrazione su un database reale. Eserciti Java Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Java Academy?

Non è richiesta alcuna esperienza precedente. Java Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Testcontainers: test di integrazione con database reali»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Java Academy?

Sì. Ogni lezione Java Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Test parametrizzati con @CsvSource e @MethodSource
  2. Mockito avanzato: ArgumentCaptor e spy
  3. Slice di test Spring Boot: @WebMvcTest e @DataJpaTest
  4. Testcontainers: test di integrazione con database reali
← Torna a Java Academy