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
@Testcontainersy@Containerpara gestionar el ciclo de vida del contenedor. - Copia
init-db.sqlen el directorio de inicialización del contenedor para que PostgreSQL lo ejecute al iniciar. - Utiliza
@DynamicPropertySourcepara registrar los detalles de conexión del contenedor con Spring Boot. - Prueba características específicas de PostgreSQL como
ON CONFLICT DO NOTHINGque 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).