当前位置: 首页 > 知识库问答 >
问题:

如何在 Junit5 中的函数中正确测试Kafka模板.send()?

谷梁波
2023-03-14

我正在学习如何编写测试,尤其是有生产者的测试。我不能发布所有的类,因为它是巨大的(而不是我的,我应该通过改变测试来练习使用KafkaTemplate)。我不知道应该如何测试这样的电话。

我得到一个NPE是因为我正在测试的函数中有一个producer.send(“主题”,JsonObject)。函数是这样构建的:

@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。但是我不太明白如何“指导”发送事件在producer.sendEvent()调用中使用KafkaTemplate?

解决方案编辑:我将< code>@Autowired改为用构造函数注入它。效果很好!下面是完整的类和方法

@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;
   }
}

共有1个答案

姜德泽
2023-03-14

您应该使用构造函数注入而不是@Autowared


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
}

如果无法更改类的构造函数,则可以使用@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类是否有@Autowired和构造函数参数?自动连线只适用于bean,通常类要么有默认构造函数和@Autowired依赖项,要么通过构造函数注入所有内容。

如果我提供的这些选项对您不起作用,请添加有关类的构造函数和总体设计的更多详细信息。

 类似资料:
  • 在JUnit 4中,通过使用注释很容易跨一堆类测试不变量。关键是一组测试正在针对单个参数列表运行。 如何在JUnit 5中复制这一点,而不使用JUnit-vintage? 不适用于测试类。听起来可能是合适的,但该注释的目标也是一个方法。 此类 JUnit 4 测试的一个示例是:

  • 我正在迁移到JUnit5,我想知道在JUnit5中是否有一种简单的方法可以知道测试何时失败,就像我们在使用TestWatcher的JUnit4中那样。 我做了一些研究,发现了一些类似的问题,但仍未解决,比如这样一个问题:https://github.com/junit-team/junit5/issues/542因为大多数问题都很老,所以我想问一下,以防最近有一个解决方案。 想法是能够做一个屏幕截

  • 我有一个返回[异常,字符串]的方法 } 现在我为类B和I存根方法验证编写测试 是否可以以这种方式存根以返回函数的右(......)?

  • 我正在使用 节点14 FireBase-Functions-Test:0.2.3 FireBase-Admin:9.6.0 FireBase-函数:3.13.2 FireBase工具:9.8.0 所以我想使用firebase云函数对我的firestore触发器函数执行单元测试,我从这里的文档中阅读了步骤。 我想使用执行单元测试。所以我假设我将在脱机模式下初始化SDK。文件上说 如果您希望编写完全脱

  • 问题内容: 我写了JUnit5扩展。但是我找不到方法如何获得测试结果。 扩展看起来像这样: 有什么提示如何获得测试结果? 问题答案: 正如其他答案所指出的那样,JUnit会将失​​败的测试与异常进行通信,因此可以使用来了解发生的情况。请注意,这很容易出错,因为以后运行的扩展程序仍可能无法通过测试。 另一种方法是注册自定义TestExecutionListener。不过,这两种方法都有点round回

  • 我想使用测试异常是否工作良好。 例如,假设I test queue。