Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to exclude source code from coverage measurement in IntelliJ IDEA?

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.

like image 890
Christian Hujer Avatar asked Jan 02 '15 21:01

Christian Hujer


2 Answers

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.

like image 84
Peter Lawrey Avatar answered Oct 15 '22 05:10

Peter Lawrey


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...

like image 24
akagixxer Avatar answered Oct 15 '22 04:10

akagixxer