【问题标题】:No code coverage when using PowerMock to test final class with static methods Java使用 PowerMock 使用静态方法 Java 测试最终类时没有代码覆盖
【发布时间】:2021-04-05 19:13:03
【问题描述】:

我正在为 final 类编写一个测试用例,该类在其中定义了 static 方法。 现在测试用例运行良好,但是当我点击代码覆盖率时,它显示 0%,尽管测试用例运行良好。

我正在使用 PowerMockEasyMock 并使用 Junit4

我的班级

public class Meals {
    public static String getName(String name) {
        if (name == null) {
            return "bad";
        } else {
            return "good";
        }
    }
}

还有我的测试用例

import static org.junit.Assert.assertEquals;

import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(Meals.class)
public class MealsTest {

    @Before
    public void setUp() throws Exception {
        PowerMock.mockStatic(Meals.class);
    }

    @Test
    public void testMeals() {

        EasyMock.expect(Meals.getName(null)).andReturn("bad");
        PowerMock.replayAll();
        assertEquals("bad", Meals.getName(null));
        PowerMock.verifyAll();

    }

}

据我所知,这是因为注释 PreparefortestRunWith ,但我不确定。

所以任何帮助将不胜感激。

【问题讨论】:

    标签: java testing junit powermock easymock


    【解决方案1】:

    众所周知,PowerMock 会杀死代码覆盖率。我认为这是因为他们在一个特殊的类加载器中加载了自定义类,而代码覆盖工具没有检测到这段代码,因为它是事后的。除了不使用 PowerMock 之外,我认为这些不是解决方案。

    我们是否同意您的测试当前未测试任何内容?这只是测试 PowerMock 是否正常工作。

    【讨论】:

      【解决方案2】:

      如果您使用的是 jacoco + Gradle,您可以通过以下方式启用离线仪表

      task instrument(dependsOn: [classes, project.configurations.jacocoAnt]) {
          inputs.files classes.outputs.files
          File outputDir = new File(project.buildDir, 'instrumentedClasses')
          outputs.dir outputDir
          doFirst {
              project.delete(outputDir)
              ant.taskdef(
                      resource: 'org/jacoco/ant/antlib.xml',
                      classpath: project.configurations.jacocoAnt.asPath,
                      uri: 'jacoco'
              )
              def instrumented = false
              if (file(sourceSets.main.java.outputDir).exists()) {
                  def instrumentedClassedDir = "${outputDir}/${sourceSets.main.java}"
                  print sourceSets.main.java.outputDir
                  ant.'jacoco:instrument'(destdir: instrumentedClassedDir) {
      
                      fileset(dir: sourceSets.main.java.outputDir, includes: '**/*.class')
                  }
                  //Replace the classes dir in the test classpath with the instrumented one
                  sourceSets.test.runtimeClasspath -= files(sourceSets.main.java.outputDir)
                  sourceSets.test.runtimeClasspath += files(instrumentedClassedDir)
                  instrumented = true
              }
              if (instrumented) {
                  test.jvmArgs += '-noverify'
              }
          }
      }
      test {
          dependsOn instrument
          useJUnit()
          finalizedBy jacocoTestReport // report is always generated after tests run
      }
      

      代码归功于https://github.com/esdk/g30l0/commit/82af4c9aad50aadc40d940471fe1b934473170c7

      这是一个未解决的问题 https://github.com/gradle/gradle/issues/2429

      【讨论】:

        猜你喜欢
        • 2018-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多