You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android Instrumented Test中Mock Final类(Mockito 2.X)

解决Mockito 2.X在Android Instrumented Test(ART环境)中Mock Final类的问题

我明白你遇到的困扰了——在JVM本地单元测试里能正常Mock PowerManager这类Final类,但切换到运行在ART环境的Instrumented Test就报错,这本质是ART的字节码限制和Mockito默认配置不兼容导致的。下面是一步步的解决方案:

步骤1:调整依赖配置

首先确保你的app/build.gradle中,Android Instrumented Test的依赖包含Mockito Android库和inline扩展(后者是支持Final类Mock的关键):

androidTestImplementation 'org.mockito:mockito-android:2.28.2' // 可替换为最新的2.X稳定版本
androidTestImplementation 'org.mockito:mockito-inline:2.28.2' // 两个依赖版本需保持一致

步骤2:添加Mockito配置文件

因为Instrumented Test的资源路径和本地单元测试不同,你需要手动创建配置文件开启inline模式:

  1. 在app/src/androidTest/resources目录下新建mockito-extensions文件夹
  2. 在该文件夹内创建名为org.mockito.plugins.MockMaker的文件,文件内容仅一行:
mock-maker-inline

这个文件会告知Mockito使用inline生成策略,该策略能绕过ART对Final类的字节码限制。

步骤3:优化测试代码(可选但推荐)

你的测试代码可以做些小调整,提升可读性和避免过时API问题:

import android.content.Context;
import android.os.PowerManager;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.reset;

@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {

    @Mock
    private Context mockedContext;
    @Mock
    private PowerManager mockedPowerManager;

    private ShutdownServicesReqSig rebootSig = ShutdownServicesReqSig.newBuilder(ShutDownType.REBOOT_SYSTEM)
            .setReason("test")
            .build();

    // 用MockitoRule自动初始化@Mock注解的对象,简化代码
    public MockitoRule mockitoRule = MockitoJUnit.rule();

    @Test
    public void testRestart() throws InterruptedException {
        when(mockedContext.getSystemService(Context.POWER_SERVICE)).thenReturn(mockedPowerManager);

        assertTrue(executor.requestShutdown(rebootSig));
        Thread.sleep(1000);

        verify(mockedPowerManager).reboot(any(String.class));
        reset(mockedPowerManager);
    }
}

说明:替换了过时的Matchers为ArgumentMatchers,并使用@Mock注解简化Mock对象的创建流程。

额外说明

  • 本地单元测试能正常运行的原因:JVM环境下Mockito默认的字节码修改机制可以直接支持Final类,但ART环境有更严格的字节码验证规则,必须依赖inline模式才能突破限制。
  • 若项目使用AndroidX,记得把android.support.test相关依赖替换为AndroidX版本(比如androidx.test.ext:junit:1.1.3),避免兼容性冲突。

内容的提问来源于stack exchange,提问作者CR Sardar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:55:29