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

Android Robolectric单元测试中从Drawable加载Bitmap为空问题排查

单元测试中BitmapFactory.decodeResource返回null的原因及解决办法

这问题我之前踩过坑,核心原因是单元测试的运行环境和Activity的运行环境完全不同:

  • 咱们在Activity里用的是真实的应用Context,它能正常访问Android系统的资源加载机制,所以BitmapFactory.decodeResource可以顺利读取R.drawable.my_image。
  • 而普通的Local单元测试(就是放在test目录下的测试)是直接在电脑的JVM上运行的,没有完整的Android系统环境,资源加载的逻辑根本走不通,所以decodeResource会返回null。

下面给你两种解决思路:

1. 改用仪器化测试(推荐用于资源加载相关测试)

如果你的测试必须依赖真实的Drawable资源,那应该把测试代码放到androidTest目录下(仪器化测试),这里的测试会运行在Android设备或模拟器上,能拿到真实的应用Context。

示例代码:

@RunWith(AndroidJUnit4::class)
class BitmapLoadingTest {
    @Test
    fun testBitmapLoadingAndCompression() {
        // 获取真实的应用Context
        val appContext = ApplicationProvider.getApplicationContext<Context>()
        
        val bitmapImage = BitmapFactory.decodeResource(appContext.resources, R.drawable.my_image)
        // 先验证Bitmap不为空
        assertNotNull("Bitmap should not be null", bitmapImage)
        
        // 执行你的压缩逻辑
        val bos = ByteArrayOutputStream()
        val quality = 10
        bitmapImage.compress(Bitmap.CompressFormat.JPEG, quality, bos)
        val pixels = bos.toByteArray()
        
        // 验证压缩结果
        assertTrue("Compressed byte array should not be empty", pixels.isNotEmpty())
    }
}

2. 模拟Bitmap对象(用于Local单元测试)

如果不想用仪器化测试,只想在Local单元测试里验证压缩逻辑,那可以直接创建一个模拟的Bitmap,跳过真实的资源加载步骤:

示例代码:

@Test
fun testBitmapCompressionLogic() {
    // 创建一个空白的Bitmap来模拟真实的Drawable加载结果
    val mockBitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888)
    
    // 执行压缩逻辑
    val bos = ByteArrayOutputStream()
    val quality = 10
    mockBitmap.compress(Bitmap.CompressFormat.JPEG, quality, bos)
    val pixels = bos.toByteArray()
    
    // 验证压缩后的结果符合预期
    assertTrue(pixels.isNotEmpty())
}

这样就能在Local单元测试里专注验证压缩逻辑,不用依赖真实的资源文件啦。

内容的提问来源于stack exchange,提问作者Baptiste Amato

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:45:51