【问题标题】:Can we mock finally block in unit testing [closed]我们可以在单元测试中模拟 finally 块吗?
【发布时间】:2017-06-20 16:23:03
【问题描述】:

在我的代码中,我有一个 try-finally 方法。我不想 finally 阻止我的单元测试。我可以在我的类中模拟整个 finally 块吗,因为在我的情况下它只是记录?我正在使用 PowerMockito用于我的单元测试。

try {
    String foo = obj.myMethod();
} finally {
    logger.info(obj.webService());
}

【问题讨论】:

  • 为什么在测试时记录问题?
  • 为什么要模拟一个块。您只能模拟对象,不能模拟块或循环。
  • 为什么不只是模拟记录器?
  • @alfasin 因为我在调用我的 web 服务时遇到空指针异常,并且在返回期间我不希望我的 web 服务有任何值。
  • 您应该注入一个模拟 obj 并可能为 obj.webService() 创建一个期望。在生产中,代码将调用obj.webService(),因此在您的测试中您也应该这样做。

标签: java unit-testing junit powermockito


【解决方案1】:

您编写的类将调用logger.info(obj.webService()),因此您的测试应该执行该操作。

根据是否在测试中运行您的被测类做不同的事情并不是一个好主意。您可以更改的只是它的协作者,通常是用模拟替换它们。

在这种情况下,obj 是协作者。所以注入obj 的模拟。根据您的测试意图,使用默认值可能就足够了,因此记录器将记录null,或者您可能需要指定when 以使obj.webService() 返回一个有效对象,或者您甚至可能想要验证它是否被调用。

【讨论】:

  • 我在做一个假设,但假设 NPE 是记录器iteslf 为空。适当地嘲笑主要合作者 foo 很棒,但没有解决第二个合作者 logger。
【解决方案2】:

在 cmets 中,您声明要避免在测试期间调用 Web 服务。

我不希望在我返回期间从我的网络服务中获得任何价值。

我认为如果您的应用程序的日志级别设置为 WARNING 或更高,您也不希望这样做。 (这里我假设java默认日志)

解决方案很简单:使用采用Supplier 的日志记录表单:Logger.info(Supplier<String> msgSupplier)

所以你的 finally 块会变成:

} finally {
    logger.info(() -> obj.webService());
}

那么,对于您的测试,或者在生产中,这只是将您的日志记录设置为 Level.NONE 的一种情况,供应商将永远不会被执行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-25
    • 2013-08-14
    • 2018-04-19
    • 2019-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-02
    相关资源
    最近更新 更多