JaCoCo branch coverage try with resources

2.6k Views Asked by At

I have a method that I am trying to unit-test. I cannot post the actual code, but it looks like this:

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

JaCoCo is telling me that I am missing 4/8 branches on each of the try-with-resource blocks. I am testing that someCondition is true and someCondition is false, and JaCoCo shows that block completely covered.

I read this question, and I understand from the accepted answer that the issue is in how the byte code is generated.

I would like to be able to better understand how to identify the various branches that are generated, and then I can make a better judgement on wether to test them or not (are they unreachable, etc).

2

There are 2 best solutions below

0
On BEST ANSWER

Per the change history in version 0.8.2:

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

I've tested this out locally using openjdk java8, and my try-with-resources now reports 100% branch coverage (even though the IOException is never thrown in my tests).

While it is good to test this behavior out, there are times when you can't easily reproduce such exceptions. For instance, in a method that just returns an open port:

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

I know of no simple way to force this code to throw IOException without adding a bunch of confusing and unnecessarily complicated code, just to pass a branch coverage check. Luckily, the new (v0.8.2) jacoco library gives this method 100% coverage with a single test just calling Assert.assertNotEquals(0, portChecker.getOpenPort());.

1
On

You have to test every Exception and every condition. But JaCoCo sometimes failed to identify correctly what is covered or not.