@SpringBootTest@TestcontainersclassApplicationTests{@ContainerstaticPostgreSQLContainer<?>postgres=newPostgreSQLContainer<>("postgres:15-alpine").withDatabaseName("testdb");@DynamicPropertySourcestaticvoidconfigureProperties(DynamicPropertyRegistryregistry){registry.add("spring.datasource.url",postgres::getJdbcUrl);registry.add("spring.datasource.username",postgres::getUsername);registry.add("spring.datasource.password",postgres::getPassword);registry.add("spring.jpa.hibernate.ddl-auto",()->"create-drop");}@TestvoidcontextLoads(){// Test with real database}}
@TestcontainersclassKafkaIntegrationTest{@ContainerstaticKafkaContainerkafka=newKafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:7.5.0"));@DynamicPropertySourcestaticvoidkafkaProperties(DynamicPropertyRegistryregistry){registry.add("spring.kafka.bootstrap-servers",kafka::getBootstrapServers);}@AutowiredprivateKafkaTemplate<String,String>kafkaTemplate;@AutowiredprivateMessageListenermessageListener;@TestvoidshouldProcessMessage()throwsException{Stringtopic="test-topic";Stringmessage="Hello Kafka!";kafkaTemplate.send(topic,message);// Wait for message processingawait().atMost(Duration.ofSeconds(10)).until(()->messageListener.getReceivedMessages().size()==1);assertEquals(message,messageListener.getReceivedMessages().get(0));}}
Use Case 3: Multi-Container Mikroservices Prüfverfahren¶
@TestcontainersclassMicroservicesIntegrationTest{staticNetworknetwork=Network.newNetwork();@ContainerstaticPostgreSQLContainer<?>database=newPostgreSQLContainer<>("postgres:15-alpine").withNetwork(network).withNetworkAliases("database").withDatabaseName("orders");@ContainerstaticGenericContainer<?>redis=newGenericContainer<>("redis:7-alpine").withNetwork(network).withNetworkAliases("redis").withExposedPorts(6379);@ContainerstaticGenericContainer<?>orderService=newGenericContainer<>("order-service:latest").withNetwork(network).withExposedPorts(8080).withEnv("DATABASE_URL","jdbc:postgresql://database:5432/orders").withEnv("REDIS_HOST","redis").dependsOn(database,redis).waitingFor(Wait.forHttp("/actuator/health").forStatusCode(200));@TestvoidshouldCreateOrder(){StringbaseUrl="http://"+orderService.getHost()+":"+orderService.getMappedPort(8080);// Make HTTP request to order serviceRestTemplaterestTemplate=newRestTemplate();Orderorder=newOrder("item-123",2);ResponseEntity<Order>response=restTemplate.postForEntity(baseUrl+"/orders",order,Order.class);assertEquals(HttpStatus.CREATED,response.getStatusCode());assertNotNull(response.getBody().getId());}}
@Testcontainers@DataMongoTestclassProductRepositoryTest{@ContainerstaticMongoDBContainermongodb=newMongoDBContainer("mongo:6.0").withExposedPorts(27017);@DynamicPropertySourcestaticvoidmongoProperties(DynamicPropertyRegistryregistry){registry.add("spring.data.mongodb.uri",mongodb::getReplicaSetUrl);}@AutowiredprivateProductRepositoryproductRepository;@TestvoidshouldFindProductsByCategory(){// Insert test dataproductRepository.save(newProduct("Laptop","Electronics",999.99));productRepository.save(newProduct("Mouse","Electronics",29.99));productRepository.save(newProduct("Desk","Furniture",299.99));// Query by categoryList<Product>electronics=productRepository.findByCategory("Electronics");assertEquals(2,electronics.size());assertTrue(electronics.stream().allMatch(p->p.getCategory().equals("Electronics")));}}
** Verwenden Sie statische Behälter für Prüfklassen*: Teilen Sie Container über alle Testmethoden, um Startzeit und Ressourcennutzung zu reduzieren
- Umsetzen von Containern*: Aktivieren testcontainers.reuse.enable=true für schnellere lokale Entwicklungstestzyklen
- ** Mittel aufstocken Verwenden Sie __INLINE_CODE_102_ oder versuchen Sie mit Ressourcen, wenn Sie Behälter außerhalb der JUnit Integration manuell verwalten
- **Benutzen Sie spezifische Bild-Tags*: Vermeiden Sie latest Tag; verwenden Sie spezifische Versionen wie postgres:15-alpine für reproduzierbare Tests
**Test gegen produktionsähnliche Abhängigkeiten*: Verwenden Sie echte Datenbank-Engines und Nachrichtenbroker anstelle von eingebetteten Versionen
**Isolate Testdaten*: Stellen Sie sicher, dass jeder Test eigene Daten erstellt und reinigt, um Testinterdependien zu verhindern
** Verwenden Sie Netzwerk-Aliases*: Erstellen Sie benutzerdefinierte Netzwerke und verwenden Sie aussagekräftige Alias für die intercontainer Kommunikation
Implementierung von Gesundheitskontrollen Konfigurieren Sie immer richtige Wartestrategien, um sicherzustellen, dass die Behälter vollständig bereit sind, bevor die Tests durchgeführt werden