繁体   English   中英

对 Kafka SpringBoot 生产者进行单元测试

[英]Unit Testing a Kafka SpringBoot producer

我正在尝试为集成到文件中的 Kafka Producer 创建单元测试。 这是我的 Kafka 生产者:

FileName: MessageProducer.java

public boolean sendMessage(ReceivedMessage message) {
    private String topicName = "output-flow";
    try{
        logger.info("Sending message: {} to topic: {}", message, topicName);
        kafkaProducer.send(topicName, message).get();
        return true;
    } catch (Exception e){
        logger.error("Error sending message: {} to topic: {}", message, topicName, e);
        return false;
    }
}

这是我到目前为止为我的单元测试所做的,显然,根本没有成功:

@Mock
private KafkaTemplate<String, ReceivedMessage > kafkaProducer;

private static final String TRANSACTION_TOPIC = "test";

// Function for parameterized values

@ParameterizedTest
@MethodSource("getTransactionProvider")
public void sendMessageTest(ReceivedMessage message) {
    MessageProducer mockProducer = new MessageProducer(kafkaProducer);
    when(kafkaProducer.send(TRANSACTION_TOPIC, message)).thenReturn({no idea what to put here});
    when(mockProducer.sendMessage(message)).thenReturn(true);
    assertTrue(mockProducer.sendMessage(message));
}

// Test for exception
// Fails too
@ParameterizedTest
@MethodSource("getTransactionProvider")
public void sendMessageTest_ThrowsException(ReceivedMessage message) {
    MessageProducer mockProducer = new MessageProducer(kafkaProducer);
    when(kafkaProducer.send(TRANSACTION_TOPIC, message)).thenThrow(new RuntimeException());
    assertThrows(RuntimeException.class, () -> mockProducer.sendMessage(null));
}

我得到Exception: org.opentest4j.AssertionFailedError: Expected java.lang.RuntimeException to be thrown, but nothing was thrown. 对于后面的单元测试。

如果我理解你的问题,你应该返回一个新的 SendResult ,它会用你期望的数据实现方法

https://docs.spring.io/spring-kafka/api/org/springframework/kafka/support/SendResult.html

并将其包装在 Future 中

ListenableFuture<SendResult<K,V>>

或者,使sendMessage方法无效(或返回一个 Future 本身),并传入一个生产者回调参数,该参数通过发送而不是使其阻塞。 然后你可以断言回调的响应

欢迎来到SO...

为什么你的测试用例会失败? 因为你的逻辑不会抛出错误。

您的 function 不会抛出异常,因为您在 function 中捕获了如下异常并返回 boolean 值。

catch (Exception e){
        logger.error("Error sending message: {} to topic: {}", message, topicName, e);
        return false;
    }

在这种情况下,您需要测试 function 是否返回 false。

正如我之前评论的那样,以后不要通过调用 get 方法来阻塞主线程 object。您可以简单地实现未来的回调,一旦获得结果就可以调用,如下所示

public void sendMessage(ReceivedMessage message) {
    private String topicName = "output-flow";
    try{
        logger.info("Sending message: {} to topic: {}", message, topicName);
          ListenableFuture<SendResult<String, String>> future  = kafkaProducer.send(topicName, message);


                future.addCallback(new ListenableFutureCallback<SendResult<String, String>>() {
    
                    @Override
                    public void onSuccess(SendResult<String, String> result) {
    
                        System.out.println("Message Sent  " + result.getRecordMetadata().timestamp());
                        //your logic for the success scenario    
                    }
    
                    @Override
                    public void onFailure(Throwable ex) {
    
                        System.out.println(" sending failed  ");
// your logic if failed
throw new RuntimeException("Kafka Failed");
   
    
                    }
                });
    
    } catch (Exception e){
        logger.error("Error sending message: {} to topic: {}", message, topicName, e);
        throw new RuntimeException("Exception occurred");
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM