我知道这个问题的答案是:您不会测试私有方法,而只会测试最终会导致私有方法调用的公共方法。
但是 在我的情况下,公共方法实际上启动了与kafka的使用者/连接,因此我只想测试收到kafka消息时完成的逻辑。 我不想公开该逻辑方法,因为没有人会在kafka基础设施之外使用它,但是我仍然想对在那里完成的逻辑进行单元测试。
什么是最佳实践解决方案?我可以根据需要更改代码
这里有一些例子:
有问题的私有方法
private void handleConsumerRecord(ConsumerRecord<PK, byte[]> cr, Acknowledgment acknowledgment) throws IOException {
//logic to be tested
}
调用私有逻辑方法的私有方法
/**
* Initialize the kafka message listener
*/
private void initConsumerMessageListenerContainer(ProducerFactory<PK, V> producerFactory) {
if (!processAsBatch) {
// start a acknowledge message listener to allow the manual commit
acknowledgingMessageListener = (cr, acknowledgment) -> {
try {
handleConsumerRecord(cr, acknowledgment);
} catch (IOException e) {
log.error("Failed to handle consumed message, commiting message and performing irrecoverableException actions");
exceptionHandlerManager.getIrrecoverableExceptionHandler().performAction(null, cr.value(), cr.topic(), cr.key());
}
};
// start and initialize the consumer container
container = initContainer(acknowledgingMessageListener, producerFactory);
}
这是开始一切的公共方法
/**
* Start the message consumer
* The record event will be delegate on the onMessage()
*/
public void start(ProducerFactory<PK, V> producerFactory) {
initConsumerMessageListenerContainer(producerFactory);
container.start();
}
我试图写的单元测试
kafkaByteArrConsumer.getAcknowledgingMessageListener().onMessage(record, acknowledgment);
doThrow(TemporaryException.class).when(kafkaByteArrConsumer).getConsumerMessageLogic().onMessage(record.value(), acknowledgment);
Mockito.verify(exceptionHandlerManager.getTemporaryExceptionHandler(), Mockito.times(1))
.performAction();
如您所见,getAcknowledgingMessageListener
不会初始化initConsumerMessageListenerContainer()
,因此在模拟.getConsumerMessageLogic().onMessage
时我将无法访问handleConsumer方法
(被//一些要测试的逻辑调用)
答案 0 :(得分:1)
一个不错的折衷办法是将您的方法更改为保护甚至包私有的,然后将单元测试放在同一包中。单元测试类不必位于同一根目录下。假设您的源位于“源”文件夹下,而测试则位于“测试”文件夹下。只需将测试类驻留在同一包中即可。在此问题中可以找到非常详细的答案:How can we test package-private class? 。您的问题可能与该问题重复
答案 1 :(得分:0)
嗯,有些人使用PowerMock来测试私有方法等,但是我总是建议避免这种情况。也许您应该考虑在这里稍微改变一下逻辑,甚至最好考虑使用Kafka MockConsumer等。