Kotlin测试报错:提供的参数无法调用任意匹配函数,如何测试Flow<List>?
问题解决:Android Room测试Flow类型返回值assertThat报错
错误根源
当前报错核心来自两个问题:
dao.getAll()返回的是Flow<List<Plant>>响应式流对象,不是直接的列表数据,直接对Flow对象做列表包含匹配本身就不成立- 混用了Hamcrest和Truth两种断言库的API,
assertThat(参数, Matcher).isTrue()不符合任意一种断言库的语法规范
解决方案步骤
- 步骤1:添加协程测试依赖
在Module级别的build.gradle依赖中添加协程测试库,用于便捷获取Flow的发射值:dependencies { // 版本可根据你的项目协程版本适配调整 testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3" androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3" } - 步骤2:修改测试代码,获取Flow实际值
用first()操作符取Flow第一次发射的数据库快照值,同时调整断言写法:
如果你用的是Truth断言库:
如果你用的是Hamcrest断言库:import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.first @Test fun WriteAndReadPlant() = runTest { 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 byte_arr: ByteArray = stream.toByteArray() val plant = Plant( id = Math.random().toLong(), name = "Vera", icon = byte_arr, type = "Aloe", waterTip = "2 times a week ,Water more in summer", petTip = "Is not safe to digest for pets" ) dao.insertPlant(plant) // 取Flow第一个发射值,拿到实际的列表数据 val plants = dao.getAll().first() // 正确的Truth断言写法 assertThat(plants).contains(plant) }import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.collection.IsCollectionWithSize.hasItem import kotlinx.coroutines.flow.first // 断言部分替换为 assertThat(plants, hasItem(plant)) - 步骤3:确保Plant实体类支持值匹配
Kotlin中直接将Plant声明为data class,会自动生成equals、hashCode方法,列表的contains匹配才会按属性值判断,否则会按内存引用匹配,就算属性完全一致也会返回不包含。
内容的提问来源于stack exchange,提问作者Edita Komarova
相关产品推荐
相关产品推荐

