I am trying to mock my response from KafkaTemplate.send()
My main class is setup like this
@Override
public QueryServiceSendStatus sendMessage(
String topic, Integer partition, String key, byte[] value, List<Header> recordHeaders) {
try {
ListenableFuture result =
kafkaTemplate
.send(new ProducerRecord<>(topic, partition, key, value, recordHeaders));
Notice I don't have callbacks on my Listenable Future and have the class marked @Async, I have tried implementing this with callbacks as well and still run into the same issue. When running my full application and running a sort of smoke test the kafka code works as expected and writes the correct data onto its intended topic.
Here is my test:
@SpringBootTest
@ExtendWith(MockitoExtension.class)
class QueryServiceProducerTest {
@InjectMocks private QueryServiceProducer classUnderTest;
@Mock KafkaTemplate<String, byte[]> template;
QueryServiceRequest queryServiceRequest;
QueryServiceSendStatus expectedStatus;
@BeforeEach
void setup() throws ExecutionException, InterruptedException {
int offset = 0;
expectedStatus =
QueryServiceSendStatus.builder()
.offset(0L)
.partition(0)
.error(null)
.partition(0)
.topic("topic")
.timestamp(123L)
.build();
queryServiceRequest =
new QueryServiceRequest(String.valueOf(UUID.randomUUID()), "data", "topic");
RecordMetadata recordMetadata =
new RecordMetadata(
new TopicPartition(queryServiceRequest.getTopic(), offset), 0L, 0L, 123L, 0L, 0, 0);
SettableListenableFuture<SendResult<String, byte[]>> future = new SettableListenableFuture<>();
future.set(new SendResult<>(new ProducerRecord<>("topic", 0, queryServiceRequest.getId(), "data".getBytes(), null), recordMetadata));
given(template.send(any(ProducerRecord.class)))
.willReturn(future); // Have Also used when().thenReturn
}
@Test
void testQueryServiceProducerIsOK() {
QueryServiceSendStatus status =
classUnderTest.sendMessage(
queryServiceRequest.getTopic(),
0,
queryServiceRequest.getId(),
queryServiceRequest.getData().getBytes(),
null);
Assertions.assertEquals(expectedStatus, status);
}
In my main class I want to do some stuff on the future to get the RecordMetadata to build my response to the class that called the producer (You can see I have am returning an object called QueryServiceSendStatus that I will be storing in a DB). The problem is during my test when I call kafkaTemplate.send(new ProducerRecord<>());
result variable never gets populated even though I am mocking the kafkaTemplate.
I have tried mocking the SettableListenerFuture along with the SendResult that I use to create the SettableListenerFuture, but for some reason when send()
is always called it is null.