【问题标题】:RuntimeException: Method putExtra in android.content.Intent not mockedRuntimeException:android.content.Intent 中的方法 putExtra 未模拟
【发布时间】:2016-07-27 15:31:46
【问题描述】:

我正在为一个应用模块编写单元测试。我不知何故在模拟 Android 调用时遇到了问题。我想要为我的测试用例使用 InstrumentationTest。

这是我的课程。从一个不太重要的模型类开始:

package de.mk_xappo.mockitoexample;

import java.io.Serializable;

public class SpecialData implements Serializable {

    int someData_1;
    int someData_2;

    public int getSomeData_1() {
        return someData_1;
    }

    public void setSomeData_1(int someData_1) {
        this.someData_1 = someData_1;
    }

    public int getSomeData_2() {
        return someData_2;
    }

    public void setSomeData_2(int someData_2) {
        this.someData_2 = someData_2;
    }
}

这是我用于启动活动的集中管理器:

package de.mk_xappo.mockitoexample;

import android.content.Context;
import android.content.Intent;

public class IntentManager {
    private Context context;

    public IntentManager(Context context) {
        this.context = context;
    }

    public boolean goToSpecialActivity(SpecialData specialData) {
        Intent intent = new Intent(context, SpecialActivity.class);
        intent.putExtra(SpecialActivityManager.INTENT_EXTRA_SPECIAL_DATA, specialData);
        context.startActivity(intent);
        return true;
    }
}

这是我的“专业”经理:

包 de.mk_xappo.mockitoexample;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;

public class SpecialActivityManager {

    private final SharedPreferences sharedPreferences;
    private final IntentManager intentManager;
    private boolean specialShouldBeShown = true;

    public static final String INTENT_EXTRA_SPECIAL_DATA = "INTENT_EXTRA_SPECIAL_DATA";

    public SpecialActivityManager(Context context) {
        sharedPreferences = context.getSharedPreferences(context.getPackageName() + ".special", Activity.MODE_PRIVATE);
        this.intentManager = new IntentManager(context);
    }

    public void showSpecial(SpecialData specialData) {
        if (specialShouldBeShown) {
            intentManager.goToSpecialActivity(specialData);
        }
    }
}

这是我的单元测试:

包 de.mk_xappo.mockitoexample;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;

import org.junit.Before;
import org.junit.Test;

import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class SpecialManagerTest {

    private Context context;
    private SharedPreferences sharedPreferences;
    private SharedPreferences.Editor editor;
    private SpecialActivityManager specialActivityManager;
    private Intent intent;

    @Before
    public void setUp() throws Exception {
        context = mock(Context.class);
        intent = mock(Intent.class);
        sharedPreferences = mock(SharedPreferences.class);
        editor = mock(SharedPreferences.Editor.class);

        when(context.getSharedPreferences(anyString(), anyInt())).thenReturn(sharedPreferences);
        when(sharedPreferences.edit()).thenReturn(editor);
        when(editor.putBoolean(anyString(), anyBoolean())).thenReturn(editor);

        specialActivityManager = new SpecialActivityManager(context);
    }

    @Test
    public void testShowSpeciall() throws Exception {
        SpecialData specialData = mock(SpecialData.class);
        IntentManager intentManager = mock(IntentManager.class);

        when(intentManager.goToSpecialActivity(specialData)).thenReturn(true);

        specialActivityManager.showSpecial(specialData);

        verify(intent).putExtra(SpecialActivityManager.INTENT_EXTRA_SPECIAL_DATA, specialData);
        verify(context).startActivity(intent);
    }
}

现在我得到以下异常:

java.lang.RuntimeException: Method putExtra in android.content.Intent not mocked. See http://g.co/androidstudio/not-mocked for details.

        at android.content.Intent.putExtra(Intent.java)
        at de.mk_xappo.mockitoexample.IntentManager.goToSpecialActivity(IntentManager.java:18)
        at de.mk_xappo.mockitoexample.SpecialActivityManager.showSpecial(SpecialActivityManager.java:23)
        at de.mk_xappo.mockitoexample.SpecialManagerTest.testShowSpeciall(SpecialManagerTest.java:46)
        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.junit.runner.JUnitCore.run(JUnitCore.java:137)
        at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
        at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
        at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
        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.AppMain.main(AppMain.java:144)

我已经尝试关注this 链接。但后来我无法验证我的方法调用:

verify(intent).putExtra(SpecialActivityManager.INTENT_EXTRA_SPECIAL_DATA, specialData);
verify(context).startActivity(intent);

那么是否有可能以某种方式模拟putExtra() 方法,或者您有什么其他的解决方案吗?

【问题讨论】:

    标签: android android-intent junit mocking mockito


    【解决方案1】:

    在您的SpecialManagerTest 中,您只需要测试是否调用了intentManager.goToSpecialActivity(specialData)

    如果启动新活动是IntentManager 的责任,应该在那里进行测试。

    首先要使SpecialManager 可测试,您需要将其属性作为参数传递(这样您就可以模拟它们):

    public class SpecialActivityManager {
    
        private final SharedPreferences sharedPreferences;
        private final IntentManager intentManager;
        private boolean specialShouldBeShown = true;
    
        public static final String INTENT_EXTRA_SPECIAL_DATA = "INTENT_EXTRA_SPECIAL_DATA";
    
        public SpecialActivityManager(Context context, IntentManager intentManager) {
            sharedPreferences = context.getSharedPreferences(context.getPackageName() + ".special", Activity.MODE_PRIVATE);
            this.intentManager = intentManager;
        }
    
        public void showSpecial(SpecialData specialData) {
            if (specialShouldBeShown) {
                intentManager.goToSpecialActivity(specialData);
            }
        }
    }
    

    那么你的测试应该是:

    public class SpecialActivityManagerTest {
    
        private IntentManager intentManager;
        private SpecialActivityManager specialActivityManager;
    
        @Before
        public void setUp() throws Exception {
            Context context = mock(Context.class);
            SharedPreferences sharedPreferences = mock(SharedPreferences.class);
            intentManager = mock(IntentManager.class);
    
            when(context.getSharedPreferences(anyString(), anyInt())).thenReturn(sharedPreferences);
    
            specialActivityManager = new SpecialActivityManager(context, intentManager);
        }
    
        @Test
        public void testShowSpeciall() throws Exception {
            SpecialData specialData = mock(SpecialData.class);
    
            specialActivityManager.showSpecial(specialData);
            verify(intentManager).goToSpecialActivity(specialData);
        }
    }
    

    【讨论】:

    • 这家伙真懂!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-13
    • 1970-01-01
    • 2021-03-02
    • 2020-05-24
    • 2023-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多