如何在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模式:
- 在
app/src/androidTest/resources目录下新建mockito-extensions文件夹 - 在该文件夹内创建名为
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
相关产品推荐
相关产品推荐

