java - cobertura 未能通过反射类测试

标签 java maven cobertura

我在我的项目上运行 mvn clean cobertura:cobertura install 但其中一个测试失败了。

该测试尝试访问一个带有通过反射编写的构建器的类。

public MyClass(Builder builder) throws Exception {
    Field[] classFields = MyClass.class.getDeclaredFields();
    Field[] classBuilderFields = Builder.class.getDeclaredFields();
    for (int i = 0; i < classBuilderFields.length; i++) {
        Field fieldInClass = classFields[i];
        Field fieldInBuilder = classBuilderFields[i];
        fieldInBuilder.setAccessible(true);
        String fieldNameInClass = fieldInClass.getName();
        String fieldNameInBuilder = fieldInBuilder.getName();
        if (null != fieldNameInClass && null != fieldNameInBuilder && fieldNameInClass.equals(fieldNameInBuilder)) {
            fieldInClass.set(this, fieldInBuilder.get(builder));
        } else {
            throw new Exception("");
        }
    }
}

我调试了代码,发现 cobertura 在我的类 __cobertura_counters 中“实现”了它自己的一个变量。这是异常(exception)情况:

java.lang.IllegalAccessException: Can not set static final [I field com.domain.MyClass.__cobertura_counters to
    at sun.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:73)
    at sun.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:77)
    at sun.reflect.UnsafeQualifiedStaticObjectFieldAccessorImpl.set(UnsafeQualifiedStaticObjectFieldAccessorImpl.java:77)
    at java.lang.reflect.Field.set(Field.java:741)
    at com.domain.MyClass.<init>(MyClass.java:217)
    at com.domain.MyClassTest.setUp(MyClassTest.java:57)
    at com.domain.MyClass$Builder.build(MyClass.java:197)

我该如何解决这个问题?

最佳答案

是的,Cobertura 添加了这个字段,因此它可以跟踪访问了哪些代码。出于类似的目的,其他代码覆盖工具添加了类似的字段。生成的字段具有此签名:

public static final transient int[] __cobertura_counters;

您可以做的只是忽略代码中的 transient 字段。你可以这样做:

if (!Modifier.isTransient(fieldInClass.getModifiers())) {
    // do a thing
}

但是请注意,非生成的代码也可以有 transient 字段,因此根据您要反射(reflect)的代码,这可能是也可能不是一个选项。否则,您唯一的选择 (AFAIK) 是简单地检查是否 fieldInClass.getName().equals("__cobertura_counters")

通常,编译器生成的字段会被标记为“合成的”。例如,javac 为非静态内部类生成的 this$0 字段是合成的。检查它非常容易:fieldInClass.isSynthetic()。但是,出于某种原因,Cobertura 不遵循此约定。

关于java - cobertura 未能通过反射类测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34018248/

相关文章:

java - 调用方法,但不会返回值。 java

java - 如何将特定日期设置到 Joda Time DateTime 对象中?

java - Maven 依赖作为模块

java - mvn 任务失败时如何使 Ant 构建失败?

android - 我可以在 PowerMock 的单元测试中使用 Cobertura 吗?

maven - 错误 SLF4J : Class path contains multiple SLF4J bindings jenkins cobertura maven

java - 在 Spring Mvc Java 中记录未处理的异常

java - IcePDF 查看器自定义帮助

maven - Tycho 的 Maven 多模块中的自定义 pom.xml 文件名

python - 无法在 azure 管道中发布代码覆盖率