I'm trying to unit test the callbacks from the kafkaTemplate.send() but its not working as expected. here's the code snippet of the code im trying to test.
@Override
public void sendMessage(String topicName, String message) {
ListenableFuture<SendResult<String, String>> future = kafkaTemplate.send(topicName, message);
future.addCallback(new ListenableFutureCallback<SendResult<String, String>>() {
@Override
public void onSuccess(SendResult<String, String> result) {
System.out.print("Success")
}
@Override
public void onFailure(Throwable ex) {
System.out.print("Failed")
}
});
}
and this is the unit test code
private KafkaTemplate<String, String> kafkaTemplate;
private KafkaService kafkaService;
private SendResult<String, String> sendResult;
private ListenableFuture<SendResult<String, String>> future;
private RecordMetadata recordMetadata
private String topicName
private String message
def setup() {
kafkaTemplate = Mock(KafkaTemplate.class)
kafkaService = new KafkaService(kafkaTemplate);
topicName = "test.topic"
message = "test message"
sendResult = Mock(SendResult.class);
future = Mock(ListenableFuture.class);
recordMetadata = new RecordMetadata(new TopicPartition(topicName, 1), 1L, 0L, 0L, 0L, 0, 0);
}
def "Test success send message method"() {
given:
sendResult.getRecordMetadata() >> recordMetadata
kafkaTemplate.send(_ as String, _ as String) >> future
when:
kafkaService.sendMessage(topicName, message)
then:
// catch success or failed here.
1 * kafkaTemplate.send(_,_) >> {arguments ->
final String topicNameParam = arguments.get(0)
final String messageParam = arguments.get(1)
assert topicNameParam == topicName
assert messageParam == message
}
}
based on the debugger future is null on this scenario
ListenableFuture<SendResult<String, String>> future = kafkaTemplate.send(topicName, message); // future null
future.addCallback(new ListenableFutureCallback<SendResult<String, String>>() { // future null
i already read a lot of answers here but it does not solved the issue or havent they explain it well that i would understand where the problem is. like this one https://stackoverflow.com/a/56677098
thanks for the help in advance!
You are making a typical Spock beginner's mistake when trying to combine mocking and stubbing: First declare a stub result in the given:
block and later a checked mock interaction (without stub result) in the then:
block. But mocking and stubbing always have to happen in the same interaction as described in the manual chapter I linked to. The manual also explains that the interaction in the then:
block wins in your case, i.e. because you do not specify a stub result there, the result will default to null
.
Furthermore, you make the argument verification much more difficult than necessary. Just use simple argument constraints instead. Your test will pass if you change it like this:
def "Test success send message method"() {
given:
sendResult.getRecordMetadata() >> recordMetadata
// kafkaTemplate.send(_ as String, _ as String) >> future
when:
kafkaService.sendMessage(topicName, message)
then:
// catch success or failed here.
1 * kafkaTemplate.send(topicName, message) >> future
}