Funciones del ciclo de vida (callbacks) de JUnit 5
Al realizar pruebas con Testcontainers, se desea iniciar los contenedores requeridos antes de ejecutar cualquier prueba y eliminarlos después. Puedes usar los métodos de callback del ciclo de vida de JUnit 5 @BeforeAll y @AfterAll para esto:
package com.testcontainers.demo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.List;
import java.util.Optional;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.testcontainers.postgresql.PostgreSQLContainer;
class CustomerServiceWithLifeCycleCallbacksTest {
static PostgreSQLContainer postgres = new PostgreSQLContainer(
"postgres:16-alpine"
);
CustomerService customerService;
@BeforeAll
static void startContainers() {
postgres.start();
}
@AfterAll
static void stopContainers() {
postgres.stop();
}
@BeforeEach
void setUp() {
customerService =
new CustomerService(
postgres.getJdbcUrl(),
postgres.getUsername(),
postgres.getPassword()
);
customerService.deleteAllCustomers();
}
@Test
void shouldCreateCustomer() {
customerService.createCustomer(new Customer(1L, "George"));
Optional<Customer> customer = customerService.getCustomer(1L);
assertTrue(customer.isPresent());
assertEquals(1L, customer.get().id());
assertEquals("George", customer.get().name());
}
@Test
void shouldGetCustomers() {
customerService.createCustomer(new Customer(1L, "George"));
customerService.createCustomer(new Customer(2L, "John"));
List<Customer> customers = customerService.getAllCustomers();
assertEquals(2, customers.size());
}
}Esto es lo que hace el código:
PostgreSQLContainerse declara como un campo estático (static field). El contenedor se inicia antes de todas las pruebas y se detiene después de todas las pruebas de esta clase.@BeforeAllinicia el contenedor,@AfterAlllo detiene.@BeforeEachinicializaCustomerServicecon los parámetros JDBC del contenedor y elimina todas las filas para proporcionar una base de datos limpia a cada prueba.
Observaciones clave:
- Debido a que el contenedor es un campo estático, se comparte entre todos los métodos de prueba de la clase. Puedes declararlo como un campo no estático y usar
@BeforeEach/@AfterEachpara iniciar un nuevo contenedor por prueba, pero esto no se recomienda ya que consume muchos recursos. - Incluso sin detener explícitamente el contenedor en
@AfterAll, Testcontainers utiliza el contenedor Ryuk para limpiar los contenedores automáticamente cuando la JVM finaliza.