--- title: Write tests with Testcontainers linkTitle: Write tests description: Test the Spring Boot REST API using Testcontainers and REST Assured. weight: 20 --- To test the REST API, you need a running Postgres database and a started Spring context. Testcontainers spins up Postgres in a Docker container and `@DynamicPropertySource` connects it to Spring. ## Write the test Create `CustomerControllerTest.java`: ```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 customers = List.of( new Customer(null, "John", "john@mail.com"), new Customer(null, "Dennis", "dennis@mail.com") ); customerRepository.saveAll(customers); given() .contentType(ContentType.JSON) .when() .get("/api/customers") .then() .statusCode(200) .body(".", hasSize(2)); } } ``` Here's what the test does: - `@SpringBootTest` starts the full application on a random port. - A `PostgreSQLContainer` starts in `@BeforeAll` and stops in `@AfterAll`. - `@DynamicPropertySource` registers the container's JDBC URL, username, and password with Spring so that the datasource connects to the test container. - `@BeforeEach` deletes all customer rows before each test to prevent test pollution. - `shouldGetAllCustomers()` inserts two customers, calls `GET /api/customers`, and verifies the response contains 2 records.