Android Room数据库JUnit测试中contains()方法报未解析引用错误
你的判断是正确的,报错核心原因是dao.getAll()返回值为Flow<List<Plant>>类型,而非直接的列表实例,Flow本身没有contains方法,因此触发了类型不匹配的错误。
解决步骤
1. 取出Flow中发射的列表值
Room返回的Flow会在数据库数据变更时自动发射最新的列表,你可以使用Flow的first()扩展操作符获取插入数据后第一次发射的列表结果,操作符会在拿到值后自动停止收集Flow,非常适合单值测试场景。
2. 确保Plant类的匹配逻辑正确
Kotlin中普通类的equals方法默认比较对象内存地址,你插入的plant实例和从数据库查询出的plant实例是两个不同的对象,就算属性完全一致也会被contains判定为不匹配。只需要将Plant类声明为data class,Kotlin会自动生成基于所有属性值的equals和hashCode方法,即可解决这个问题。
修改后的测试代码
@Test fun WriteAndReadPlant() = runBlocking { val imageUrl = URL(url) val options = BitmapFactory.Options().apply { inSampleSize = 3 } val bitmap = BitmapFactory.decodeFile(imageUrl.toString(), options) val stream = ByteArrayOutputStream() bitmap.compress(Bitmap.CompressFormat.PNG, 50, stream) val byteArr: ByteArray = stream.toByteArray() val plant = Plant( id = Math.random().toLong(), name = "Vera", icon = byteArr, type = "Aloe", waterTip = "2 times a week ,Water more in summer", petTip = "Is not safe to digest for pets" ) dao.insertPlant(plant) // 新增first()调用获取Flow中的列表值 val plants = dao.getAll().first() assertThat(plants.contains(plant)).isTrue() }
可选扩展
如果你需要测试Flow的多次发射场景(比如多次插入、删除数据验证Flow的更新逻辑),可以使用Turbine库实现更复杂的Flow事件测试,当前单插入验证场景使用first()即可满足需求。
内容的提问来源于stack exchange,提问作者Edita Komarova
相关产品推荐
相关产品推荐

