I'm writing integration tests using Testcontainers in a Spring Boot application. I am testing the user service, which calls the authentication service in order to encode the password when a user is created, and I'm trying to start two containers:
A postgres:17 database
A custom-built auth-service:latest container
The Postgres container starts correctly, executes init.sql, and works perfectly.
However, the auth-service container fails with this error:
Wait strategy failed. Container exited with code 1
Caused by: java.net.ConnectException: Connection refusedWaiting for URL: http://localhost:56873/auth/health
...
Timed out waiting for URL to be accessible (http://localhost:56873/auth/health should return HTTP [200])
@SpringBootTest(
properties = {
"logging.level.org.springframework.security=DEBUG",
},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Testcontainers
@TestPropertySource(properties = {
"spring.jpa.hibernate.ddl-auto=create-drop",
})
class UserControllerIntegrationTests {
static Network network = Network.newNetwork();
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:17")
.withDatabaseName("testdb")
.withUsername("testuser")
.withPassword("testpass")
.withNetwork(network)
.withNetworkAliases("postgres-db");
@Container
static GenericContainer<?> authService = new GenericContainer<>("auth-service:latest")
.withExposedPorts(8080)
.withNetwork(network)
.withNetworkAliases("auth-service")
.waitingFor(Wait.forHttp("/auth/health")
.forStatusCode(200)
.withStartupTimeout(Duration.ofSeconds(20)));
static {
String initScriptPath = "./init.sql";
try {
MountableFile.forClasspathResource(initScriptPath);
System.out.println("✅ Testcontainers: Found init script on classpath: " + initScriptPath);
postgres.withInitScript(initScriptPath);
} catch (IllegalArgumentException e) {
System.err.println("❌ Testcontainers ERROR: Init script NOT found on classpath: " + initScriptPath);
throw new RuntimeException("Failed to locate database initialization script.", e);
}
}
@Autowired
private TestRestTemplate restTemplate;
@Value("${server.api.key}")
private String apiKey;
@Autowired
private UserRepository userRepository;
@Autowired
private ObjectMapper objectMapper;
@Autowired
private TestHelper httpTestHelper;
@Autowired
private JwtService jwtService;
@Autowired
private JwtAuthFilter jwtAuthFilter;
@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);
registry.add("api.services.auth-service", () ->
"http://" + authService.getHost() + ":" + authService.getMappedPort(8080));
}