Gradle - jacoco任务在Spring应用程序运行时添加合成字段,导致测试计数类中已声明字段的数量失败

问题描述 投票:2回答:2

我有这门课:

public class UserPurchaseUtil {
    public static final String JSON_PROP_ID = "id";
    public static final String JSON_PROP_USER_ID = "user_id";
    // See Confluence: First Time Member Promotion (FTM)
    public static final String JSON_PROP_LAST_PURCHASE_TIME = "last_purchase_time";

}

然后,我想确保我注意到这堂课的所有价值变化,通过“注意”,我想确保

  • 每次删除或添加一些常量时,测试都会失败;
  • 检查所有值。

所以我有这个测试:

@Slf4j
@RunWith(MockitoJUnitRunner.class)
public class UserPurchaseUtilTest {

    @Test
    public void testNumberOfConstantsAndTheirValues() {
        int numberOfConstants = UserPurchaseUtil.class.getDeclaredFields().length;
        // just to ensure we test all the constants' values when we add new ones. Now is 3.
        Assert.assertEquals(3, numberOfConstants);

        Assert.assertEquals("id", UserPurchaseUtil.JSON_PROP_ID);
        Assert.assertEquals("user_id", UserPurchaseUtil.JSON_PROP_USER_ID);
        Assert.assertEquals("last_purchase_time", UserPurchaseUtil.JSON_PROP_LAST_PURCHASE_TIME);
    }
}

但是,这个简单的测试失败了:

expected:<3> but was:<4>
Expected :3
Actual   :4
 <Click to see difference>

那么为什么?

编辑:

我的天啊。现在调试时,我现在可以看到第四个字段了。

private static transient boolean[] com.xxx.utils.UserPurchaseUtil.$jacocoData

这是一个Spring Boot项目。

enter image description here

java spring-boot reflection junit
2个回答
1
投票

因此,您的类具有由库添加的额外字段,创建一些异常列表以忽略与某些名称/模式匹配的字段。 也许只是忽略瞬态场?或者只获得公共领域?


1
投票

jacocojacocoTestReport相关的Gradle jacocoTestCoverageVerification相关任务干扰了我对所有类的反思检查。

我发现了这个问题:

https://github.com/jacoco/jacoco/issues/168

我的代码使用反射。当我用JaCoCo执行它时为什么会失败?

为了收集执行数据,JaCoCo检测被测试的类,它们为类添加了两个成员:私有静态字段$ jacocoData和私有静态方法$ jacocoInit()。两个成员都标记为合成。

请更改您的代码以忽略合成成员。无论如何,这也是一种很好的做法,因为Java编译器在某些情况下也会创建合成成员。

我认为在这种情况下,我应该在计算时忽略合成成员。 isSynthetic()表示成员在运行时由编译器添加(排序)。

所以它会像:

int nonSynthetic = 0;
Field[] allFields = UserPurchaseUtil.class.getDeclaredFields();
for (Field f: allFields) {
    // ignore synthetic methods, which are added at runtime by jacoco (or other libraries)
    if (!f.isSynthetic()) {
        nonSynthetic ++;
    }
}
Assert.assertEquals(3, nonSynthetic);
© www.soinside.com 2019 - 2024. All rights reserved.