如何在 Junit5 的函数中正确测试 kafkaTemplate.send()?
How to properly test kafkaTemplate.send() within a function in Junit5?
我正在学习如何编写测试,尤其是其中包含生产者的测试。我不能 post 所有 classes 因为它太大了(而且不是我的,我应该通过更改测试以使用 KafkaTemplate 来练习)。我不知道应该如何测试这样的调用。
由于我正在测试的函数中的 producer.send("topic", JsonObject),我遇到了 NPE。函数是这样构建的:
@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;
}
在单元测试中是这样的(省略无关部分):
@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
}
我们有 Mockito,我想我需要以某种方式模拟 KafkaTemplate。但是我不太明白如何“指导”sendEvent 在 producer.sendEvent()
调用中使用 KafkaTemplate?
解决方案编辑:我将 @Autowired
更改为使用构造函数注入它。效果很好!这是完整的 class 和现在的方法
@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;
}
}
你应该使用构造函数注入而不是 @Autowired
:
private KafkaTemplate<String,EventDto> kafkaTemplate;
public EventProducer(KafkaTemplate<String,EventDto> kafkaTemplate, something) {
this.kafkaTemplate = kafkaTemplate;
}
public EventDto sendEvent(Event event) {
EventDto eventToSend = this.dtoMapper.mapToDto(event, SomeEvent.class);
this.kafkaTemplate.send("topic",eventToSend);
return eventToSend;
}
这样你就可以在你的测试中注入模拟:
@Test
void testSendEvent() {
//omitted lines regarding second assert that works
KafkaTemplate<<String,EventDto>> templateMock = mock(KafkaTemplate.class);
EventProducer producer = new EventProducer(templateMock, something);
EventDto dto = producer.sendEvent(Event.newBuilder().build());
assertThat(dto).isNotNull();
//there is a second assert here that passes, nothing to do with kafka
}
如果您不能更改 class' 构造函数,您可以使用 @MockBean
:
提供一个模拟
@MockBean
KafkaTemplate<String,EventDto> kafkaTemplate;
@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
}
但是这个设计有些奇怪 - EventProducer
class 有 @Autowired
和构造函数参数吗?自动装配仅适用于 bean,通常 class 具有默认构造函数和 @Autowired
依赖项,或者通过构造函数注入所有内容。
如果我提供的这些选项不适合您,请添加有关 class 构造函数和整体设计的更多详细信息。
我正在学习如何编写测试,尤其是其中包含生产者的测试。我不能 post 所有 classes 因为它太大了(而且不是我的,我应该通过更改测试以使用 KafkaTemplate 来练习)。我不知道应该如何测试这样的调用。
由于我正在测试的函数中的 producer.send("topic", JsonObject),我遇到了 NPE。函数是这样构建的:
@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;
}
在单元测试中是这样的(省略无关部分):
@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
}
我们有 Mockito,我想我需要以某种方式模拟 KafkaTemplate。但是我不太明白如何“指导”sendEvent 在 producer.sendEvent()
调用中使用 KafkaTemplate?
解决方案编辑:我将 @Autowired
更改为使用构造函数注入它。效果很好!这是完整的 class 和现在的方法
@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;
}
}
你应该使用构造函数注入而不是 @Autowired
:
private KafkaTemplate<String,EventDto> kafkaTemplate;
public EventProducer(KafkaTemplate<String,EventDto> kafkaTemplate, something) {
this.kafkaTemplate = kafkaTemplate;
}
public EventDto sendEvent(Event event) {
EventDto eventToSend = this.dtoMapper.mapToDto(event, SomeEvent.class);
this.kafkaTemplate.send("topic",eventToSend);
return eventToSend;
}
这样你就可以在你的测试中注入模拟:
@Test
void testSendEvent() {
//omitted lines regarding second assert that works
KafkaTemplate<<String,EventDto>> templateMock = mock(KafkaTemplate.class);
EventProducer producer = new EventProducer(templateMock, something);
EventDto dto = producer.sendEvent(Event.newBuilder().build());
assertThat(dto).isNotNull();
//there is a second assert here that passes, nothing to do with kafka
}
如果您不能更改 class' 构造函数,您可以使用 @MockBean
:
@MockBean
KafkaTemplate<String,EventDto> kafkaTemplate;
@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
}
但是这个设计有些奇怪 - EventProducer
class 有 @Autowired
和构造函数参数吗?自动装配仅适用于 bean,通常 class 具有默认构造函数和 @Autowired
依赖项,或者通过构造函数注入所有内容。
如果我提供的这些选项不适合您,请添加有关 class 构造函数和整体设计的更多详细信息。