Menu

#120 Cobertura and Java Generics

open
nobody
None
5
2016-02-23
2009-09-04
Adrien
No

After wondering why cobertura kept telling that my code was not 100% i started to get annoyed because i knew that it was 100%
By doing some test i realized that Cobertura will tell you that the class definition is not covered if it contains a generic definition like

this gave me 87% code coverage
public class TextFileIOHandler extends AbstractFileIOHandler<String>{

but this gave me 100%
public class TextFileIOHandler extends AbstractFileIOHandler{

any idea why of if there is a fix?
I tried to search in the forum but it kept telling me that the search functionality is broken

thanks

Discussion

  • Julien HENRY

    Julien HENRY - 2009-11-17

    Hi,

    I have tested with
    public class App extends ArrayList<String> {
    and it works fine.

    I suggest you provide a minimal test case with full souce code that reproduce the issue.

     
  • Anonymous

    Anonymous - 2010-11-29

    I am seeing the same problem with cobertura-maven-plugin version 2.4. Here's a test case that reports 80% code coverage although the actual code coverage is 100%. Since we have requirements to go above 90% code coverage, I've had to add 'junk code' to the class to get Cobertura to report 90%+ coverage:

    public final class ChartFileNameSource implements FileNameSource<Chart> {
    private final String template;

    public ChartFileNameSource(String template) {
    this.template = Preconditions.checkNotNull(template, "template");
    }

    @Override
    public final String getFileName(Chart data) {
    return String.format(template, data.getLabel().toLowerCase());
    }
    }

    The test code (using Mockito to mock the 'chart'):

    public class ChartFileNameSourceTest {
    ChartFileNameSource source;

    Chart chart;

    @Before
    public void setUp() throws Exception {
    source = new ChartFileNameSource("test_%s.xml");
    chart = mock(Chart.class);
    }

    @Test
    public void testGetFileNameTtfb() throws Exception {
    when(chart.getLabel()).thenReturn("TTFB");

    assertEquals("test_ttfb.xml", source.getFileName(chart));
    }

    @Test
    public void testGetFileNameMixedCase() throws Exception {
    when(chart.getLabel()).thenReturn("RpS");

    assertEquals("test_rps.xml", source.getFileName(chart));
    }

    @Test(expected = NullPointerException.class)
    public void testNullLabel() throws Exception {
    source = new ChartFileNameSource(null);
    }
    }

     

    Last edit: Anonymous 2014-09-09
  • Jesus Mayordomo Sanz

    Hi,

    This issue is related to the usage of java generics and the bridge methods the compiler includes on the class file to implement the generic templates.

    IMHO this is a bug on cobertura, no bridge method should be reported as not covered, as it is not part of the code wrote itself, but added by the compiler.

    It should be simple to fix too, as those methods are clearly marked on the class file, so they could be filtered out from the report easily.

    More details on bridge methods on: http://codeidol.com/java/javagenerics/Comparison-and-Bounds/Bridges/

    As a workaround, if you really need to increase the coverage ratio, you could create especific tests like this:

    ie: for a class defined like this
    public class NotCoveredClass extends BaseClass<GenericClass>

    Instead of creating the object to test like usual
    NotCoveredClass notCoveredClass = new NotCoveredClass();

    Create the object as the BaseClass without using generics
    BaseClass notCoveredClass = new NotCoveredClass();

    Then call the method which has the bridge counterpart as usual:
    notCoveredClass.callMethod();

    This will cause the bridge method to be called instead, covering the missing function.
    If the method returns some value, you will need to cast the result as the bridge method will return Object class.

     

Log in to post a comment.