JaCoCo 分支覆盖尝试资源

JaCoCo branch coverage try with resources

我有一个方法正在尝试进行单元测试。我无法 post 实际代码,但它看起来像这样:

public int getTotal() throws MyException {
    int total = 0;
    try (ExternalResource externalResource = ExternalService.getResource()) {
        try (OtherExternal otherResource = externalResource.getOtherResource()) {
            if (someCondition) {
                total = otherResource.getTotal();
            }
        }
    }
}

JaCoCo 告诉我,我在每个 try-with-resource 块上都缺少 4/8 个分支。我正在测试 someCondition 为 true 和 someCondition 为 false,JaCoCo 显示该块已完全覆盖。

我读了 this question,我从接受的答案中了解到问题出在字节码的生成方式上。

我希望能够更好地理解如何识别生成的各种分支,然后我可以更好地判断是否测试它们(它们是否无法访问等)。

你必须测试每一个异常和每一个条件。但 JaCoCo 有时无法正确识别涵盖或不涵盖的内容。

根据版本 0.8.2 中的 change history

Branches and instructions generated by javac 11 for try-with-resources statement are filtered out

我已经在本地使用 openjdk java8 对此进行了测试,我的 try-with-resources 现在报告了 100% 的分支覆盖率(即使 IOException 从未在我的测试中抛出)。

虽然测试此行为是件好事,但有时您无法轻易重现此类异常。例如,在仅 returns 一个开放端口的方法中:

public int getOpenPort() {
    try (ServerSocket boundSocket = new ServerSocket(0)) {
        return boundSocket.getLocalPort();
    }
}

我知道没有什么简单的方法可以强制此代码抛出 IOException 而无需添加一堆令人困惑和不必要的复杂代码,只是为了通过分支覆盖检查。幸运的是,新的 (v0.8.2) jacoco 库通过调用 Assert.assertNotEquals(0, portChecker.getOpenPort());.

的单个测试为该方法提供了 100% 的覆盖率