How to mock result from KafkaTemplate
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
When unit-testing code that uses Spring Kafka's KafkaTemplate, the goal is usually to test your service logic, not Kafka itself. In most cases, that means mocking the result of send and verifying how your code reacts to success, failure, or returned metadata.
The practical detail is that modern KafkaTemplate.send methods return a CompletableFuture<SendResult<K, V>>. So the mock needs to simulate the future behavior your production code actually depends on.
Start With the Code Under Test
Suppose your service sends a message and returns the partition from the broker metadata:
This method does not care about Kafka internals. It cares about the completed future and the metadata inside SendResult. That is exactly what the unit test should control.
Mock a Successful Send
For the success path, return a completed future containing a real SendResult:
This test is fast, isolated, and expressive. It verifies your service behavior without needing a broker or embedded Kafka setup.
Mock a Failed Send
If the code under test handles exceptions, return a future that completes exceptionally:
That pattern is useful for retry logic, exception mapping, metrics, or dead-letter decisions.
When Verification Alone Is Enough
Some code sends a message and does not inspect the result. In that case, you may only need to verify the interaction:
Do not overbuild a fake SendResult if the production code never reads it. The mock should be as small as the behavior under test.
Match the Mock to Your Spring Kafka Version
Older examples on the internet may show ListenableFuture because older Spring Kafka versions used that type. Newer versions use CompletableFuture. The test pattern is the same, but the mocked type must match the API your project actually compiles against.
That is an easy place to get confused when copying snippets from older blog posts or Stack Overflow answers.
Unit Test Versus Integration Test
Mocking KafkaTemplate is for unit tests. If you need to verify serializer configuration, topic setup, or actual broker interaction, that is an integration-test concern. Mixing the two styles usually makes tests slower and harder to maintain.
A good rule is:
- unit tests mock the future and verify service logic
- integration tests use real Kafka infrastructure when the transport behavior itself matters
Common Pitfalls
The biggest mistake is mocking only the method call and forgetting that the code under test depends on the returned future. If your service awaits the future, the test must control that result explicitly.
Another common issue is using outdated examples based on ListenableFuture in a project that now expects CompletableFuture. Always match the mock type to the version you are running.
It is also easy to overcomplicate a unit test by starting a real broker when the only behavior under test is local exception handling or metadata inspection. Use integration tests only when Kafka itself is the thing being exercised.
Finally, keep the mock aligned with the actual code path. If the service ignores metadata, do not build metadata-heavy fixtures just because the API allows it.
Summary
- Mock
KafkaTemplate.sendat the future boundary your code actually uses. - Use
CompletableFuture.completedFuturefor success cases in modern Spring Kafka code. - Use an exceptionally completed future to test failure handling.
- Verify only the interaction when the send result is ignored.
- Distinguish unit tests that mock
KafkaTemplatefrom integration tests that need a real broker.
Related reading
- How to monitor consumer lag in kafka via jmx?
- How to monitor JMX metrics of Kafka broker on command line?
- How to monitor messages rate in Kafka topics?
- How to monitor queue health in celery
- How to mock the Kubernetes cluster/server?
- How to mock void methods with Mockito
- How to open rabbitmq in browser using docker container?
- How to pass data from Kafka to Spark Streaming?

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.