Search code examples
androidjunit4android-sparsearray

Strange behavior of JUnit4 with static final SparseArray field in Enum in android


I observed strange behavior of SparseArray defined as static final field of Enum while testing with JUnit4. Enum class:

public enum ConstantType {

    PI(0, Math.PI),
    E(1, Math.E),
    ;

    private static final SparseArray<ConstantType> BY_VALUE = new SparseArray<>();

    final int id;
    final double value;

    static {
        for (ConstantType type : values()) {
            BY_VALUE.append(type.id, type);
        }
    }

    ConstantType(int id, double value) {
        this.id = id;
        this.value = value;
    }

    @Nullable
    static ConstantType fromValue(int value) {
        return BY_VALUE.get(value);
    }
}

Problem is when I access method ConstantType.fromValue(0), this method returns always null. I also used debugger to check if filling of BY_VALUE was called, but strangely, debugger show this value as "null" without NullPointerException.

Replacing of SparseArray by HashMap fixed my issue, but I am curious, why SparseArray is not working.

enter image description here


Solution

  • While this question is 3 years old, it is still a relevant question.

    SparseArray (android.util.SparseArray) is part of the Android SDK, not native Java/Kotlin. Unfortunately, that means it would not behave like, for an example, an Array. Instead, it would behave like one of your classes. That means that you have to mock/fake it for it to work.

    In general, try to avoid having static fields, as they make testing harder. Had your value not been static, you could have injected a provider which could provide a mock/fake.