JaCoCo + Mockito + Android tests: Zero coverage reported

前端 未结 1 820
太阳男子
太阳男子 2021-02-06 17:43

I know there are quite a few questions (and answers) for this topic, but I\'ve tried everything I found in SO and other sites and I haven\'t found a way to make JaCoCo include c

1条回答
  •  夕颜
    夕颜 (楼主)
    2021-02-06 18:14

    am I doing something wrong?

    Let's put aside Android, because there is IMO clearly something wrong with your expectations/understanding about core thing here - mocking:

    even though I clearly have a test that exercises that class.

    By

    @Test
    public void utilMethod() {
        Util util = Mockito.mock(Util.class);
        Mockito.doReturn(10).when(util).anIntMethod();
        assertThat(util.anIntMethod(), is(10));
    }
    

    you are not testing anIntMethod, you are testing something that always returns 10, no matter what is actually written in anIntMethod.

    Coverage shows what was executed and hence absolutely correct that it is zero for anIntMethod since it is not executed.

    Mocking is used to isolate class under test from its dependencies, but not to replace it, otherwise you're not testing real code.

    Here is an example of proper usage of mocking:

    src/main/java/Util.java:

    public class Util {
      int anIntMethod(Dependency d) {
        return d.get();
      }
    }
    class Dependency {
      int get() {
        return 0;
      }
    }
    

    src/test/java/UtilTest.java:

    import org.junit.Test;
    import org.mockito.Mockito;
    
    import static org.junit.Assert.assertEquals;
    
    public class UtilTest {
      @Test
      public void utilMethod() {
        Dependency d = Mockito.mock(Dependency.class);
        Mockito.doReturn(10).when(d).get();
        assertEquals(10, new Util().anIntMethod(d));
      }
    }
    

    build.gradle:

    apply plugin: "java"
    apply plugin: "jacoco"
    
    repositories {
      mavenCentral()
    }
    
    dependencies {
      testCompile "junit:junit:4.12"
      testCompile "org.mockito:mockito-core:2.10.0"
    }
    

    And after execution of gradle build jacocoTestReport coverage is

    And case of partial mocking:

    src/main/java/Util.java:

    public class Util {
      int get() {
        return 0;
      }
    
      int anIntMethod() {
        return get();
      }
    }
    

    src/test/java/UtilTest.java:

    import org.junit.Test;
    import org.mockito.Mockito;
    
    import static org.junit.Assert.assertEquals;
    
    public class UtilTest {
      @Test
      public void utilMethod() {
        Util util = Mockito.mock(
          Util.class,
          Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS)
        );
        Mockito.doReturn(10).when(util).get();
        assertEquals(10, util.anIntMethod());
      }
    }
    

    In both cases mocked parts are shown as uncovered and this is correct.

    0 讨论(0)
提交回复
热议问题