Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java(JUnit4.xx)如何使用模拟工具使用void方法强制调用try块中的异常?_Java_Unit Testing_Junit_Mockito_Junit4 - Fatal编程技术网

Java(JUnit4.xx)如何使用模拟工具使用void方法强制调用try块中的异常?

Java(JUnit4.xx)如何使用模拟工具使用void方法强制调用try块中的异常?,java,unit-testing,junit,mockito,junit4,Java,Unit Testing,Junit,Mockito,Junit4,下面是我的代码片段。我想使用WakeupException强制调用catch块 public void run() { try { try { while (true) { LOGGER.logp(Level.INFO, CLASS_NAME, "run()", "Attempting to Poll"); ConsumerRecords<String, String> records = consu

下面是我的代码片段。我想使用WakeupException强制调用catch块

public void run() {

try {
         try {
        while (true) {
            LOGGER.logp(Level.INFO, CLASS_NAME, "run()", "Attempting to Poll");
            ConsumerRecords<String, String> records = consumer.poll(10000);
            if (records.count() == 0) {
                LOGGER.logp(Level.INFO, CLASS_NAME, "run()", "No Response. Invalid Topic");
                break;
            }
            else if(records.count()>0) {
                LOGGER.logp(Level.INFO, CLASS_NAME, "run()", "Response Received");
            }
        }

    }

    } catch (WakeupException e) {
        consumer.close();
    }

}

我只想调用WakeupException,以便获得代码块的行覆盖率。我会怎么做。顺便说一下,这是一种无效的方法。我也愿意接受有关PowerMock的建议。

看过代码后,我很确定我们要模拟的调用是
consumer.poll(…)
。我不是使用卡夫卡的专家,所以从这里开始,一切都要小心。考虑到
consumer
是被测类的一个属性,应该可以将模拟实例注入被测类,并抛出我们需要的
WakeupException
。我们创建一个
使用者的(n个附加)模拟,并模拟其
轮询(…)
-方法,以在调用时抛出所需的
唤醒异常
,而不是(或附加到-您的决定)被测类。我们没有模拟对
consumerThread3.run()
的调用,而是模拟对
consumer.poll(…)
的调用


关于你的问题的评论:“我只想调用
唤醒异常
,这样我就可以得到行覆盖率”——这永远不应该成为编写测试的理由。测试应该测试行为。如果没有要测试的行为(这种情况很少),则不要编写测试


OP编辑了问题并添加了一些附加信息。我很有信心,这篇文章的第一段应该回答这个问题。其他段落是在OP在
try
-块中添加相关代码之前编写的。它们是在更抽象的层次上写的。感兴趣的读者可以阅读,但这不是理解答案的必要条件

お楽しみください! - 请欣赏


我们想验证
catch
-块的行为。在生产代码中,
try
-块中的某些内容将抛出相应的
异常
,从而触发
catch
-块。因此,为了测试
catch
-块,我们应该模拟
try
-块中的某个内容来抛出所述的
异常

如果在块内模拟调用似乎是不可能的,那可能是因为代码不是由测试驱动开发的。你看,这种方法的一个好处是,你本质上生成了可测试的代码。如果我们被不稳定/难以测试的代码所困扰,我们有两个(或三个)选项:

  • 保持原样,不要测试它。如果没有需要测试的行为,这可能是一个有效的答案

  • 重写代码,使其可测试。根据项目的结构,这可能需要5分钟到2周或更长时间。不知道代码库很难说

  • 使用非常规工具。正常的模拟框架(如)有一定的限制,例如。其他工具,如,旨在消除这些限制。但请注意:PowerMock是在字节码级别运行的。这意味着

    • 我们不一定要测试生产中使用的字节码
    • 这可能与其他工具(例如)一起拧紧
    这些工具应该是你的最后手段,而且使用很少


“我只想调用WakeupException,以便获得该代码块的行覆盖率。”-错误的方法。不要为了测试或覆盖而测试。测试以验证行为。--你嘲笑错误的事情。模拟
try
-块中的调用,该调用实际上可能引发
WakeupException
。是否尝试测试模拟?您不应该模仿您试图测试的方法。您是否可以添加实际上需要您添加try捕获的代码?这也是为了正确地测试它而必须模仿的东西。您可能应该研究这种情况下的依赖项注入。@sandepnamburi可能是消费者需要try-catch。如果您将它设置在某个地方,您可以尝试将它从单元测试注入到类中。通常的代码气味会是,如果你的设计是不可测试的,你可以考虑一种TDD方法来避免未来:“代码>消费者<代码>如何设置在你的代码> KAFKACONSOMER测试< /代码>对象中?这就是你想要模拟的对象,你需要某种方法来注入它。@Turing85非常感谢你,我找到了它。我模仿了消费者调查,结果成功了。谢谢大家的帮助!
@Test(expected = WakeupException.class)
public void failRun() throws WakeupException, IOException {

    KafkaConsumerForTests consumerThread3;
    consumerThread3 = Mockito.mock(KafkaConsumerForTests.class);

    doThrow(new WakeupException()).when(consumerThread3).run();
    //Mockito.when(consumerThread2.run()).thenThrow(new WakeupException());

    consumerThread3.run();

}