I started learning JUnit 4 and encountered the message "1 of 4 branches missed." when testing a code fragment like
x && y
where x
and y
depend on each other in a particular way. Here is my journey and a "solution".
Let's consider the following function
public boolean isPrintable(byte c) {
return 0x20 <= c && c < 128;
}
and ignore the fact that it may not be perfect as a criterium to determine if a byte is printable or not and focus on its test-ability instead. I'm using JUnit 4 and made sure to cover all three possible "branches" within this function: c
being smaller than 0x20
, c
being between 0x20
and 128
and c
being larger. Sadly, JUnit continues to complain with the message "1 of 4 branches missed."
And I see why that may be: In the general situation, x && y
has four possible combination of values of x
and y
to be fully covered:
| | x==true | x==false |
|--- |--- |--- |
| y==true | Possibility 1 | Possibility 2 |
| y==false | Possibility 3 | Possibility 4 |
but for x=(0x20 <= c)
and y=(c < 128)
possibility 3 is not an option (because it would mean that c <= 0x20
but not c < 128
). Hence understanding not only the syntax of the code but a bit of its semantic would be necessary to realize that possibility 3 cannot happen. But fuck it, it's java so let's get out our Collector
-factory and adapter our way towards a solution:
import java.util.stream.Collectors;
import java.util.stream.IntStream;
[...]
private boolean isWithinRange(int startInclusive, int value, int endExclusive) {
return IntStream.range(startInclusive, endExclusive).boxed().collect(Collectors.toList()).contains(value);
}
public boolean isPrintable(byte c) {
return isWithinRange(0x20, c, 128);
}
On a more serious note: please leave a comment here if you have a better idea. This is not meant as a real solution, please don't copy it and use it and tell people that it's a good idea!