Monday 5 August 2013

Java: Test Coverage for Private Constructors

It is good practice to add private constructors to utility classes that are not thought to be instantiated. This is usually the case for final classes that only have static methods or provide constants (in the latter case I would suggest to use an interface).

Following this practice usually gives a bad surprise when looking at your Cobertura code-coverage report (or similar). The tool reports that the constructor is not covered - of course, because you cannot call it! This lowers your overall percentage for line-coverage and is a drawback when you otherwise try to achieve 100% line-coverage and also enforce this using mvn verify or similar methods.



Quality-Check contains a module called Quality-Test in its newest snapshot release. It includes a small utility class CoverageForPrivateConstructor which allows us to write a little JUnit-Test to provide line-coverage for the private constructor.

@Test
public void giveMeCoverageForMyPrivateConstructor() throws Exception {
 CoverageForPrivateConstructor.giveMeCoverage(StaticCheck.class);
}


This result in a code-coverage report with full test coverage also for the private constructor. Nice, isn't it?

Quality-Test and Blueprint

Quality-Check and Quality-Test version 1.3 have been released. As a major addtion, Quality-Test includes a new module for test-data generation called "Blueprint".

A complete introduction into the Blueprint module will be given here in a later post. For now, two small examples will show, how easy it is to construct objects (i.e. blueprint objects) for your unit-tests. We use the class description and a configuration as a blueprint to construct an actual object, which is ready to be used in the test-case.

final NameDTO name = Blueprint.random().with("gender", Gender.Male).construct(NameDTO.class); 

final Address address = Blueprint.def().with(String.class, "Default").with("zipCode", 12345L).construct(Address.class);

As you can see, Blueprint contains two default configurations, which either fill all attributes using default or random values. Basically, Blueprint will walk the object tree and fill all attributes with default values specified by the current configuration. Therefore, you won't get any NullPointerExceptions in your test-cases, as all attributes are filled with values. You have to define only those values on which your functional test-case actually depends. Everything else is handled by blueprint.

If you have questions regarding Blueprint, drop me a mail. A more lengthy introduction will follow soon. So far, best is you simply try it out.