[← Acknowledgement](06-acknowledgement.md) · [Module README](../README.md) # 7. Testing without installing Kafka Two options, both real brokers, and the choice is less obvious than it looks. ## `@EmbeddedKafka` — a real broker inside the JVM ```java @SpringBootTest @EmbeddedKafka(topics = "orders", partitions = 3) class KeysAndPartitionsTest { ... } ``` `spring-kafka-test` starts `EmbeddedKafkaKraftBroker` — the actual Apache Kafka broker classes, in KRaft mode, in-process. No ZooKeeper, no container, no daemon. It binds a random port and exposes it as `${spring.embedded.kafka.brokers}`: ```yaml spring: kafka: bootstrap-servers: ${spring.embedded.kafka.brokers} ``` It starts in about three seconds and needs nothing installed, which is why every transcript in this module came from it and why `./scripts/run-all.sh` works on a machine with no Docker. ## Testcontainers — the image you actually deploy ```java @TestConfiguration(proxyBeanMethods = false) public class TestcontainersConfiguration { @Bean @ServiceConnection KafkaContainer kafkaContainer() { return new KafkaContainer(DockerImageName.parse("apache/kafka:4.1.0")); } } ``` `@ServiceConnection` registers the container's bootstrap servers as the application's, which removes the `@DynamicPropertySource` block that older examples all carry. **Two coordinates changed recently and both will bite you:** ```xml org.testcontainers testcontainers-kafka test ``` Testcontainers 2.x prefixed every module artifact with `testcontainers-`, and Boot 4.1.1 imports `testcontainers-bom` 2.0.5, which manages only the new names. Using the old coordinate fails with a Maven error that does not mention the rename: ``` 'dependencies.dependency.version' for org.testcontainers:kafka:jar is missing ``` The class moved too: use `org.testcontainers.kafka.KafkaContainer` (Apache Kafka, KRaft), not the older `org.testcontainers.containers.KafkaContainer` (Confluent images, ZooKeeper). ## Which to use | | `@EmbeddedKafka` | Testcontainers | |---|---|---| | startup | ~3s | ~10s, plus image pull | | needs Docker | no | yes | | broker version | the client library's | whatever image you name | | TLS, SASL, quotas, partitions | not modelled | real | Use `@EmbeddedKafka` for the bulk of a suite and Testcontainers for the handful of tests where the difference between "the broker classes" and "the broker you deploy" matters. The [`TestcontainersConfiguration`](../src/test/java/com/ankurm/kafkabasics/TestcontainersConfiguration.java) in this module is compiled but not exercised by `run-all.sh`, because the machine that regenerates `docs/output/` has no Docker daemon — which is itself the argument for keeping both paths. [Module README](../README.md)