【问题标题】:How to unit test a catch block which does not throw any exception如何对不抛出任何异常的 catch 块进行单元测试
【发布时间】:2020-07-10 02:00:25
【问题描述】:

这是我的代码。

    @Override
    public KinesisEvent handleRequest(@NonNull KinesisEvent kinesisEvent, @NonNull Context context) {
        KinesisEvent kinesisEventReturn = kinesisEvent.clone();
        final List<KinesisEvent.KinesisEventRecord> transformedRecords = kinesisEventReturn.getRecords().stream().map(
                record -> {
                    try {
                        return decryptLog(record);
                    } catch (IOException e) {
                        log.error("Decryption did not work. See exception: ", e);
                    }
                    return record;
                }).collect(Collectors.toList());
        kinesisEventReturn.setRecords(transformedRecords);
        return kinesisEventReturn;
    }

如果你看到了,我有一个 catch 块,它捕获异常但不抛出异常。我想在单元测试中测试 catch 块。但是我找到的所有示例都是测试是否抛出异常。

如果有任何解决方法,请提供帮助。

谢谢 德鲁博

【问题讨论】:

    标签: java unit-testing junit junit4 spock


    【解决方案1】:

    您的函数遍历一个集合(流),尝试解密每条记录,并生成它返回的每条解密记录的列表。如果解密失败,则生成日志消息并将原始记录添加到列表中。

    您可以使用这样一个事实,即如果执行了 catch 块,则 kinesisEventReturn.getRecords() 的成员将在返回的列表中。因此,您的测试用例需要构造已知会导致decryptLog(record) 抛出IOException 的输入。

    IOException 被抛出/捕获时,函数的结果将至少包含来自输​​入Collection 的一个成员。您可以使用Collections.disjoint 来简化该测试:

    if (! Collections.disjoint(result, kinesisEventReturn.getRecords()) {
        // Test failed
    

    假设解密的记录总是不同于加密的记录。

    【讨论】:

    • 请您介意详细说明一下。我是这个 Java 和单元测试的新手 :( 。你告诉我要比较哪个结果?
    • 并非所有的 decryptLog(record) 调用都可能失败。更好地检查每条记录。
    • 艾伦,我赞成你的回答,因为它是正确的,并且断言条件很优雅。但是这种解释根本不适合您的目标受众。 OP自己说他是Java和测试的初学者。甚至您之前的评论也很难阅读和理解。我建议您删除评论,更新您的问题,并在技术水平较低的情况下进行解释。 !disjoint(..) 中的隐含双重否定也不会使 OP 的事情变得更容易。或者你让我编辑你的问题,然后我们都在这里删除我们的 cmets,好吗?
    • 好的,我试试看,期待您的评论。
    猜你喜欢
    • 2013-12-19
    • 2021-07-26
    • 1970-01-01
    • 2020-06-08
    • 1970-01-01
    • 2014-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多