繁体   English   中英

在单元测试中测试私有方法

[英]Testing a private method in unit testing

我知道这个问题的答案是:您不测试私有方法,而只测试最终会导致私有方法调用的公共方法。

但是在我的情况下,公共方法实际上启动了到 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 方法

(它被 //some logic to be test 部分调用)

一个好的折衷方法是将您的方法更改为受保护甚至包私有,然后将您的单元测试放在同一个包中。 单元测试类不必驻留在同一个根下。 假设您的源代码位于“source”文件夹下,而测试位于“test”文件夹下。 只需将测试类驻留在同一个包中即可。 在这个问题中可以找到一个非常详细的答案: How can we test package-private class? . 您的问题可能与该问题重复

好吧,有些人使用 PowerMock 来测试私有方法等,但我总是建议避免这种情况。 也许你应该考虑在那里稍微改变你的逻辑,或者更好地考虑 Kafka MockConsumer 等。

暂无
暂无

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

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