#java #apache-kafka #mockito
#java #apache-kafka #mockito
Вопрос:
Я пытаюсь протестировать метод, и для этого я использую mockito. Однако мой макет не попадает внутрь условия if и переходит непосредственно к строке flush.
Я хотел бы протестировать следующую ситуацию:
public class SomeClass{
@Autowired
private Producer<String, SpecificRecord> producer;
private static final Logger LOGGER = Logger.Factory.getLogger(SomeClass.class);
public void sendMessage(String topic, SpecificRecord message, Map<String,String> headers){
ProducerRecord<String, SpecificRecord> avroMessage = new ProducerRecord<>(topic, null, null, "key",message, headers);
producer.send(avroMessage, (metadata, exception) -> {
if(exception == null ) {
LOGGER.info("OK");
}else{
LOGGER.info("NOK");
}
});
producer.flush();
}
И то, что я делаю, это:
@RunWith(MockitoJUnitRunner.class)
public class SomeClassTest{
@InjectMocks
private SomeClass someclass;
@Mock
private Producer<String,SpecificRecord> producer;
@Mock
private SpecificRecord message;
@Mock
private Logger logger;
@Test
public void sendMessageTest(){
when(producer.send(any(ProducerRecord.class),any(Callback.class))).thenReturn(null);
doNothing().when(producer).flush();
someclass.sendMessage("topic", message, new HashMap<String,String>());
verify(logger).info("OK");
}
}
Что я могу сделать, чтобы правильно смоделировать эту ситуацию?
Комментарии:
1. Kafka включает класс MockProducer, который вам, вероятно, следует использовать вместо этого
2. можете ли вы привести мне пример?
Ответ №1:
Используя приведенное ниже лямбда-выражение, вы реализуете метод onCompletion интерфейса обратного вызова (Interface Callback)
(metadata, exception) -> {
if(exception == null ) {
LOGGER.info("OK");
}else{
LOGGER.info("NOK");
}
}
И поскольку вы издеваетесь над вызовом метода отправки KafkaProducer, этот обратный вызов вызываться не будет.
Итак, чтобы иметь возможность попасть внутрь обратного вызова, вы должны захватить аргумент обратного вызова и вызвать метод onCompletion, как показано ниже:
ArgumentCaptor<Callback> callBackCaptor = ArgumentCaptor.forClass(Callback.class);
Mockito.verify(producer).send(any(ProducerRecord.class), callBackCaptor.capture());
Callback kafkaCallback = callBackCaptor.getValue();
kafkaCallback.onCompletion(new RecordMetadata(null, 0, 0, 0, 0, 0, 0), null);