PrepZone Logo
PrepZone

Integration Testing with Testcontainers

Spin up a real Kafka broker in JUnit — publish and consume VaultCommerce events in CI without mocks.

Why this matters

  • VaultCommerce CI runs 200+ Kafka integration tests per PR with Testcontainers.
  • Real broker catches serializer, ACL, and protocol issues mocks miss.
  • KRaft-enabled KafkaContainer matches production 3.7+ metadata mode.
  • Parallel test isolation via dynamic bootstrap ports.
JUnit test
Kafka container
Assert events
JUnit spins up a real Kafka broker in Docker — no mocks for integration tests.

JUnit 5 setup

@Testcontainers + @Container static KafkaContainer kafka = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:7.7.0")) or official apache/kafka-native. @DynamicPropertySource injects spring.kafka.bootstrap-servers. VaultCommerce uses singleton container per test class for speed.

Key points

  • Testcontainers — Docker-based test dependencies
  • KafkaContainer — ephemeral broker per test suite
  • @DynamicPropertySource — wire Boot properties to container port
  • Singleton container — reuse across tests in class for speed
  • Schema Registry container — pair for Avro integration tests

What to test

Publish → consume round trip with Avro and Schema Registry container. Verify @KafkaListener invokes with correct payload. Test error handler routes to DLT. VaultCommerce does not mock KafkaTemplate in integration slice.

VaultCommerce rollout checklist

Before promoting changes that touch the VaultCommerce order and payment event backbone, run the staging KRaft cluster (Kafka 3.7+, Schema Registry 7.x) through a 10k events/min soak test. Compare producer request latency p99 and consumer lag per group against the pre-deploy baseline. Real broker in Docker for faithful integration tests. Document the change in the internal topic registry, attach Grafana screenshots to the change ticket, and keep an engineer on lag dashboards for 30 minutes after production rollout — roll back the service release before altering broker-level settings if lag or under-replicated partitions spike.

Java
@SpringBootTest
@Testcontainers
class OrderPublishIT {
    @Container
    static KafkaContainer kafka = new KafkaContainer(
        DockerImageName.parse("apache/kafka-native:3.7.0"));

    @DynamicPropertySource
    static void kafkaProps(DynamicPropertyRegistry registry) {
        registry.add("spring.kafka.bootstrap-servers", kafka::getBootstrapServers);
    }

    @Autowired OrderEventPublisher publisher;
    @Autowired KafkaConsumer<String, OrderPlaced> testConsumer;

    @Test
    void publishesOrderPlaced() {
        publisher.publish(new OrderPlaced("ord-1", "cust-1", 9999L, false));
        var records = KafkaTestUtils.getRecords(testConsumer, Duration.ofSeconds(5));
        assertThat(records).hasSize(1);
    }
}

Quick recall

Everything you need if you only revisit this box.

  1. Real broker in Docker for faithful integration tests.
  2. @DynamicPropertySource wires bootstrap servers.
  3. Match KRaft mode with production.

Test yourself

Answer these before moving on — recall is what makes it stick.