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

在Android JUnit5/Mockito测试中如何为Spy/Mock对象注入特定整数字段?

解决JUnit5测试中Android隐藏字段注入问题

场景说明

应用中引用的Android类存在一个隐藏字段,真机运行时,因为应用拥有android.uid.system高权限,该字段始终可访问;但在JUnit5测试环境中,该字段不存在,导致单元测试执行失败。

被测Java应用方法

/**
 * 被测Java应用中的方法
 * 
 * 参数包含一个仅运行时可访问的隐藏整数字段。真机上APK因拥有高权限(android.uid.system)运行正常,
 * 但JUnit运行时该字段无法访问
 *
 */
static void methodInMyApplication(DataProcessor dataProcessObj){

    dataProcessObj.hiddenInteger = 5;   // 该字段仅在真机运行时存在

}

Kotlin编写的JUnit5测试类

/**
 * 用Kotlin编写的JUnit 5测试类
 *
 */
@ExtendWith(MockitoExtension::class)    // JUnit5注解
class WifiUnitTests {

    @Spy
    private val spyDataProccessor: DataProcessor = DataProcessor()
    
    @Test
    fun testMyJavaMethod() {
        MyApp.methodInMyApplication(spyDataProccessor)  // 此处崩溃,因"hiddenInteger"字段不存在
    }
    
}

问题

请问如何在调用应用方法前,手动将该隐藏整数字段注入到Spy或Mock对象中?我已尝试org.junit.platform.commons.util.ReflectionUtils中的setField方法,但该方法不存在,该方法仅在Spring Framework中可用,JUnit Commons中没有。

解决方案

方案1:使用Java原生反射动态添加字段

直接用Java原生反射API给Spy对象动态添加字段并设置访问权限,无需依赖第三方工具类:

@ExtendWith(MockitoExtension::class)
class WifiUnitTests {

    @Spy
    private val spyDataProccessor: DataProcessor = DataProcessor()
    
    @Test
    fun testMyJavaMethod() {
        // 动态添加hiddenInteger字段到Spy实例的类中
        val field = Field.declareField(spyDataProccessor.javaClass, "hiddenInteger", Int::class.javaPrimitiveType)
        // 设置字段可访问
        field.isAccessible = true
        
        // 可选:提前初始化字段值,也可以由被测方法自行设置
        field.setInt(spyDataProccessor, 0)
        
        // 调用被测方法
        MyApp.methodInMyApplication(spyDataProccessor)
    }
    
}

方案2:创建子类添加字段后Spy

如果DataProcessor允许继承,可以创建一个测试用子类,手动添加字段后再Spy这个子类:

// 自定义测试用子类,添加目标字段
class TestableDataProcessor : DataProcessor() {
    var hiddenInteger: Int = 0
}

@ExtendWith(MockitoExtension::class)
class WifiUnitTests {

    @Spy
    private val spyDataProccessor: TestableDataProcessor = TestableDataProcessor()
    
    @Test
    fun testMyJavaMethod() {
        MyApp.methodInMyApplication(spyDataProccessor)
        // 可验证字段是否被正确设置为5
        assertEquals(5, spyDataProccessor.hiddenInteger)
    }
    
}

内容的提问来源于Stack Exchange,提问作者Oke Uwechue

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 04:02:53