I'm learning how to write tests and especially tests that have a producer in it. I cannot post all the classes because it's HUGE (and not mine, I should just practice by changing the test to work with KafkaTemplate). I'm lost as to how a call like this should be tested.
I'm getting a NPE because of a producer.send("topic", JsonObject) that is in the function I'm testing. The functions is built like so:
@Autowired
private KafkaTemplate<String,EventDto> kafkaTemplate;
public EventDto sendEvent(Event event) {
EventDto eventToSend = this.dtoMapper.mapToDto(event, SomeEvent.class);
this.kafkaTemplate.send("topic",eventToSend);
return eventToSend;
}
in the unit test it's like this (irrelevant parts omitted):
@Test
void testSendEvent() {
//omitted lines regarding second assert that works
EventProducer producer = new EventProducer(something);
EventDto dto = producer.sendEvent(Event.newBuilder().build());
assertThat(dto).isNotNull();
//there is a second assert here that passes, nothing to do with kafka
}
We have Mockito and I assume I need to mock the KafkaTemplate somehow. But I'm not quite getting how I can "direct" the sendEvent to use the KafkaTemplate within the producer.sendEvent() call?
Solution edit: I changed the @Autowired to injecting it with the constructor instead. Works well! Here is the full class and method now
@Service
public class EventProducer implements EventProducerInterface {
private final DtoMapper dtoMapper;
private KafkaTemplate<String,EventDto> kafkaTemplate;
@Autowired
public EventProducer (KafkaTemplate<String,EventDto> kafkaTemplate, IDtoMapper dtoMapper) {
Assert.notNull(dtoMapper, "dtoMapper must not be null");
this.dtoMapper = dtoMapper;
this.kafkaTemplate=kafkaTemplate;
}
public EventDto sendEvent(Event event) {
EventDto eventToSend = this.dtoMapper.mapToDto(event, EventDto.class);
this.kafkaTemplate.send("output-topic",eventToSend);
return eventToSend;
}
}