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

Escribe pruebas con Testcontainers

Tabla de contenidos

Para probar la API REST, necesitas una base de datos Postgres en ejecución y un contexto de Spring iniciado. Testcontainers levanta Postgres en un contenedor de Docker y @DynamicPropertySource lo conecta a Spring.

Escribe la prueba

Crea CustomerControllerTest.java:

package com.testcontainers.demo;

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.hasSize;

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import java.util.List;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.postgresql.PostgreSQLContainer;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class CustomerControllerTest {

  @LocalServerPort
  private Integer port;

  static PostgreSQLContainer postgres = new PostgreSQLContainer(
    "postgres:16-alpine"
  );

  @BeforeAll
  static void beforeAll() {
    postgres.start();
  }

  @AfterAll
  static void afterAll() {
    postgres.stop();
  }

  @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
  CustomerRepository customerRepository;

  @BeforeEach
  void setUp() {
    RestAssured.baseURI = "http://localhost:" + port;
    customerRepository.deleteAll();
  }

  @Test
  void shouldGetAllCustomers() {
    List<Customer> customers = List.of(
      new Customer(null, "John", "[email protected]"),
      new Customer(null, "Dennis", "[email protected]")
    );
    customerRepository.saveAll(customers);

    given()
      .contentType(ContentType.JSON)
      .when()
      .get("/api/customers")
      .then()
      .statusCode(200)
      .body(".", hasSize(2));
  }
}

Esto es lo que hace la prueba:

  • @SpringBootTest inicia la aplicación completa en un puerto aleatorio.
  • Un PostgreSQLContainer se inicia en @BeforeAll y se detiene en @AfterAll.
  • @DynamicPropertySource registra la URL JDBC, el nombre de usuario y la contraseña del contenedor con Spring para que el origen de datos (datasource) se conecte al contenedor de prueba.
  • @BeforeEach elimina todas las filas de clientes antes de cada prueba para evitar la contaminación de las pruebas.
  • shouldGetAllCustomers() inserta dos clientes, realiza una llamada GET /api/customers y verifica que la respuesta contenga 2 registros.