Compartir comentarios
Las respuestas se generan en base a la documentación.

Utilizar la extensión JUnit 5 para mayor control

Tabla de contenidos

Si la URL JDBC especial no satisface tus necesidades, o necesitas más control sobre la creación del contenedor (por ejemplo, para copiar scripts de inicialización), utiliza la extensión JUnit 5 de Testcontainers:

@DataJpaTest
@TestPropertySource(properties = {
    "spring.test.database.replace=none"
})
@Testcontainers
class ProductRepositoryTest {

  @Container
  static PostgreSQLContainer postgres =
    new PostgreSQLContainer("postgres:16-alpine")
      .withCopyFileToContainer(
        MountableFile.forClasspathResource("sql/init-db.sql"),
        "/docker-entrypoint-initdb.d/init-db.sql");

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

  @Autowired
  ProductRepository productRepository;

  @Test
  @Sql("/sql/seed-data.sql")
  void shouldGetAllProducts() {
    List<Product> products = productRepository.findAll();
    assertEquals(2, products.size());
  }

  @Test
  @Sql("/sql/seed-data.sql")
  void shouldNotCreateAProductWithDuplicateCode() {
    Product product = new Product(3L, "p101", "Test Product");
    productRepository.createProductIfNotExists(product);
    Optional<Product> optionalProduct = productRepository.findById(
      product.getId()
    );
    assertThat(optionalProduct).isEmpty();
  }
}

Este enfoque:

  • Utiliza @Testcontainers y @Container para gestionar el ciclo de vida del contenedor.
  • Copia init-db.sql en el directorio de inicialización del contenedor para que PostgreSQL lo ejecute al iniciar.
  • Utiliza @DynamicPropertySource para registrar los detalles de conexión del contenedor con Spring Boot.
  • Prueba características específicas de PostgreSQL como ON CONFLICT DO NOTHING que no funcionarían con H2.

Resumen

  • Utiliza la URL JDBC especial (jdbc:tc:postgresql:...) como la forma más rápida de cambiar de H2 a una base de datos real: es un cambio de una sola propiedad.
  • Utiliza la extensión JUnit 5 cuando necesites más control sobre el contenedor (scripts de inicialización personalizados, variables de entorno, etc.).
  • Ambos enfoques funcionan con pruebas de Spring Data JPA (@DataJpaTest) y JdbcTemplate (@JdbcTest).

Lecturas adicionales