In a project, I have a Utility class which looks like this:
public final class Util {
private Util() {}
public static String method1(InputStream in) {...}
public static String method2(BufferedReader in) {...}
public static String method3(File file) {...}
}
The class is a Utility class in the sense that it contains only static
methods.
Therefore it is declared final
and its constructor is private
.
Creating instances or deriving subclasses would simply not make any sense.
I have a suite of unit tests which tests the project.
I am using IntelliJ IDEA to run the tests, measure and visualize the code coverage.
The constructor of the Utility class Util
now brings down coverage.
I would like to see a 100% on 100% logical coverage.
Code like the private constructor of the Utility class brings down the coverage.
Is there a possibility, preferably by means of an annotation, to mark a method or constructor as not relevant for code coverage in order to exclude such code from the coverage reports and thus getting a 100% coverage displayed?
I know that in general hiding code from the coverage report is lying to your own disadvantage. I wouldn't mind if the report would have a list of "ignored items" - actually, that would be good, to check if someone is ignoring stuff which shouldn't be ignored. The point is really about code for which coverage makes no sense, like the private constructor of a Utility class.
I've tried to find if annotations.jar
contains a candidate. The only annotation which looked even remotely as if it could do it was TestOnly
, but it does not fulfill this purpose.
I also peeked around in plugins/coverage/lib/*.jar
and couldn't find a candidate, but maybe I just missed it?
Update This question is obsolete now. Meanwhile, IntelliJ IDEA as well as Jacoco learned how to ignore the coverage of private constructurs that don't have callers. I do not know of any other example of intentionally unreachable code in Java that would spark a conversation for exclusion from coverage reports.
Update 2 This question may become relevant again about the accessors of Java record classes.
I use enum
for utility classes and most coverage tools know to ignore it's methods.
public enum Util { ;
enum
are final
with private
constructors by default.
This question is currently over a year old; however, I thought I could offer an alternative to ignoring private constructors in unit tests. Although fairly unlikely, it is possible to circumvent a private constructor in Java. Also, its possible the class could be modified in the future, someone could add a constructor etc... Having a unit test verifying this can feel redundant, but it does add another level of clarity of intent. A failing unit test would certainly catch my eye, "I caused a unit test to fail, am I sure I know what I'm changing here?"
Without further ado here is some sample code.
Here we have a class with a private constructor.
public final class ClassWithPrivateCtor
{
private ClassWithPrivateCtor()
{
throw new AssertionError(String.format(
"Illegal instantiation of class: %s.",
this.getClass().getName()));
}
}
This is one way to invoke a private constructor in Java.
private static <T> void invokePrivateConstructor(final Class<T> type)
throws Throwable
{
final Constructor<T> constructor = type.getDeclaredConstructor();
constructor.setAccessible(true);
try
{
constructor.newInstance();
}
catch (InvocationTargetException ex)
{
throw ex.getTargetException();
}
}
And this is how I use it in my unit tests.
@Test(
description = "Verify ClassWithPrivateCtor private constructor fails.",
expectedExceptions = AssertionError.class)
public void classWithPrivateCtorTest()
throws Throwable
{
invokePrivateConstructor(ClassWithPrivateCtor.class);
}
I've made it a habit to verify private constructors this way just to be clear about the original intent of the class whether its a utility class or a class with constants etc...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With