I'm getting an error: java.lang.ClassCastException: Z cannot be cast to java.lang.String while trying to run coverage (EclEmma) on a Junit test. If I run the test regularly (without coverage) then it passes.

This is the code (all the fields in the class are Strings):

@Override
public Map<String, String> getErrors() throws IllegalAccessException, IllegalArgumentException {

    Map<String, String> errors = new HashMap<String, String>();

    for (Field field : this.getClass().getDeclaredFields()) {
        field.setAccessible(true);
        String value = (String) field.get(this);

        if (value.equals("N")) {
            if (!errors.containsKey(field.getName())) {
                errors.put(field.getName(), value);
            }
        }
    }
    return errors;
}
share
    
Is the code obfuscated? – Henry Aug 18 '16 at 7:37
up vote 0 down vote accepted

The problem is that to produce the code coverage EclEmma adds a field private static final transient boolean[] $jacocoData to your class.

Since this field is only present during code coverage runs, the normal unit test passes, but the code coverage run fails: your original code is not expecting this non-String field.

The best solution is to check if the field you are seeing is really a String field and otherwise skipping the test of the field value:

for (Field field : this.getClass().getDeclaredFields()) {
    field.setAccessible(true);
    if (field.getType() != String.class) {
        continue;
    }
    String value = (String) field.get(this);

    if (value.equals("N")) {
        if (!errors.containsKey(field.getName())) {
            errors.put(field.getName(), value);
        }
    }
}
share

Try to do this:

String value = "null";
if(field.get(this) != null)
    value = field.get(this).toString();

Instead of this:

String value = (String) field.get(this);
share
2  
Note that this might fail if field.get(this) is null. Better to use Objects.toString(field.get(this)). – Andy Turner Aug 18 '16 at 7:42
    
You're rhight, I correct myself – Nathaël Noguès Aug 18 '16 at 7:44
    
@AndyTurner how can it be, that you're always there and correct and still less than 30k repu? :) – xenteros Aug 18 '16 at 7:46
    
@xenteros 30k rep requires 150 days at daily maximum to reach. If I actually tried to reach that, I doubt I'd still have a job :) – Andy Turner Aug 18 '16 at 7:47
    
@xenteros yes, I do. No, they don't. – Andy Turner Aug 18 '16 at 7:49

Finally, I checked that the field value is instance of String and replaced casting to String with the function toString().

String value = null;
Object fieldValue = field.get(this);
if (fieldValue instanceof String) {
    value = fieldValue.toString();
}

if ("N".equals(value)) {
    if (!errors.containsKey(field.getName())) {
        errors.put(field.getName(), value);
    }
}
share

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.