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
相关产品推荐
相关产品推荐

