首页 > 解决方案 > Android 单元测试在枚举查找初始化时失败

问题描述

我尝试编写单元测试,但lookup.put(e.code, e);在此类中失败:

package com.toto.mbc.ui.enums;

import android.util.SparseArray;
import com.toto.mbc.R;

public enum ModuleValidationStateEnum {

    CREATED(1, R.drawable.infos_icon_module_created,  R.drawable.infos_icon_module_created_white),

    VALIDATED(2, R.drawable.infos_icon_module_validated, R.drawable.infos_icon_module_validated_white),

    ERROR(3, R.drawable.icone_croix_rouge, R.drawable.icone_croix_blanche),

    WAIT_FOR_REPLACEMENT(4, R.drawable.tdb_remplacement_icon_red, R.drawable.tdb_remplacement_icon_white);

    private int code;
    private Integer icon;
    private Integer iconSelected;

    private static final SparseArray<ModuleValidationStateEnum> lookup = new SparseArray<>();

    ModuleValidationStateEnum(final int code, final Integer icon, final Integer iconSelected) {
        this.code = code;
        this.icon = icon;
        this.iconSelected = iconSelected;
    }

    static {
        for (final ModuleValidationStateEnum e : ModuleValidationStateEnum.values()) {
            lookup.put(e.code, e);
        }
    }

    public static ModuleValidationStateEnum getEnumByCode(int code) {
        return lookup.get(code);
    }

    public int getCode() {
        return code;
    }

    public Integer getIcon() {
        return icon;
    }

    public Integer getIconSelected() {
        return iconSelected;
    }
}

除了这个例外

java.lang.ExceptionInInitializerError
    at com.toto.mbc.business.models.util.CriRgValidatorTest.isPoseDisjoncteurNotValidatedWhenDeposeValidated_TestPoseDepose(CriRgValidatorTest.java:45)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
    at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)
Caused by: java.lang.RuntimeException: Method put in android.util.SparseArray not mocked. See http://g.co/androidstudio/not-mocked for details.
    at android.util.SparseArray.put(SparseArray.java)
    at com.toto.mbc.ui.enums.ModuleValidationStateEnum.<clinit>(ModuleValidationStateEnum.java:41)
    ... 31 more

我真的不明白为什么,这是我要测试的课程:

public class CriRgValidator {

    private final CroManager croManager;
    private static final Logger LOG = LogConfigHelper.getLogger(CriRgValidator.class);

    public CriRgValidator(CroManager croManager) {
        this.croManager = croManager;
    }

    public boolean isPoseDeviceNotValidatedWhenRemovalValidated(
            List<AbstractModuleTDBItem> blockRealisationModules) {

        String logStart = "Contrôle pose réalisée : ";
        LOG.debug(logStart + "bloquant : debut vérification removal doit avoir une pose réalisé");

        boolean isPoseDeviceNotValidated = false;
        boolean isRemovalDeviceValidated = false;
        boolean noProblem = false;

        for (AbstractModuleTDBItem module : blockRealisationModules) {
            if (module.isOperationMateriel()) {
                ModuleTdbOpMatItem opMat = (ModuleTdbOpMatItem) module;
                if (opMat.isDeviceEnPlace()) {
                    if (opMat.isOperationPose()) {
                        isPoseDeviceNotValidated =
                                ModuleValidationStateEnum.VALIDATED != opMat.getValidationState();
                    } else if (opMat.isRemoval()) {
                        isRemovalDeviceValidated =
                                ModuleValidationStateEnum.VALIDATED == opMat.getValidationState();
                    }
                }
            }
        }

        if (isRemovalDeviceValidated) {
            LOG.debug(logStart + "pose réalisée : 'true', removal réalisée : '" +
                    isPoseDeviceNotValidated + "'");
            return isPoseDeviceNotValidated;
        } else {
            LOG.debug(logStart + "validé, pas de blocage");
            return noProblem;
        }
    }

}

这是实际的测试:

@RunWith(MockitoJUnitRunner.class)
public class CriRgValidatorTest {

    CriRgValidator criRgValidator;
    CroManager croManager;

    @Before
    public void setup() throws Exception {
        croManager = Mockito.mock(CroManager.class);
        criRgValidator = new CriRgValidator(croManager);
    }

    @Test
    public void isPoseDeviceNotValidatedWhenremovalValidated_TestPoseremoval() throws Exception {
        //given
        ModuleTdbOpMatItem modulePose = new ModuleTdbOpMatItem(new Long(CodeCategorieMateriel
                .DEVICE.getCode()), ModuleValidationStateEnum.VALIDATED, CodeTypeOperation
                .POSE.getCode());
        ModuleTdbOpMatItem moduleremoval = new ModuleTdbOpMatItem(new Long(CodeCategorieMateriel
                .DEVICE.getCode()), ModuleValidationStateEnum.VALIDATED, CodeTypeOperation
                .REMOVAL.getCode());
        List<AbstractModuleTDBItem> realisationModules = new ArrayList<>();
        realisationModules.add(modulePose);
        realisationModules.add(moduleremoval);

        //when
        boolean result =
                criRgValidator.isPoseDeviceNotValidatedWhenremovalValidated(realisationModules);

        //then
        Assert.assertTrue(result);
    }

}

我真的不明白它想让我嘲笑什么(以及如何嘲笑)。

由于代码匿名化,可能会出现一些语法错误。

谢谢。

标签: androidunit-testingjunitmockito

解决方案


好吧,如果我正确阅读了我的错误,我会看到它告诉我去http://g.co/androidstudio/not-mocked了解更多详细信息。

将此添加到我的 graddle conf 解决了问题:

android {
..

    testOptions {
            unitTests {
                returnDefaultValues = true
            }
        }

}

推荐阅读