android - Room 的 DAO 方法返回 Flowable 的订阅者不会收到有关插入实体的通知
问题描述
我有一个带有一个实体和 DAO 的 Room 数据库,它允许插入对象并将SELECT
查询作为Flowable
. 当我订阅它Flowable
,然后将一个新对象插入数据库时,不会产生新的结果。
@Database(entities = [User::class], version = 1)
abstract class TestDatabase : RoomDatabase() {
abstract val dao: UserDao
}
@Dao
interface UserDao {
@Insert
fun insert(user: User)
@Query("SELECT * FROM User")
fun observeUsers(): Flowable<List<User>>
}
@Entity
data class User(@PrimaryKey val id: Int, val name: String)
失败的测试:
@RunWith(AndroidJUnit4::class)
class ObserveUsersTest {
@Test
fun observeUsersTest() {
val db = Room.inMemoryDatabaseBuilder(
InstrumentationRegistry.getContext(), TestDatabase::class.java
).build()
val dao = db.dao
val user = User(0, "George")
val test = dao.observeUsers().test()
dao.insert(user)
test.assertValue(listOf(user))
db.close()
}
}
失败:
java.lang.AssertionError: Expected: [User(id=0, name=George)] (class: SingletonList), Actual: [] (latch = 1, values = 0, errors = 0, completions = 0)
如果在调用 to 之前完成插入,则测试通过observeUsers
:
dao.insert(user)
dao.observeUsers().test().assertValue(listOf(user))
我究竟做错了什么?
解决方案
我猜你没有等待足够长的时间来观察插入的结果。如果insert
在内部是异步的(即使您没有使用 RxJava API 定义它),您可能会过早地订阅和测试单个值。
awaitCount
在断言单个值之前尝试使用测试方法(因为你有一个无限的Flowable
,所以awaitTerminalEvent
当然不起作用):
dao.observeUsers()
.test()
.awaitCount(1, TestWaitStrategy.SLEEP_10MS, 5000)
.assertValue(listOf(user));
推荐阅读
- autodesk-forge - 将点从 DWG 模型坐标转换为 Autodesk Forge 查看器坐标
- javascript - 下拉菜单中的 Bootstrap 4 选项卡
- android - Aapt2 异常即使在禁用它之后
- sql - 根据多列中的最大值检索SQL中的行
- sql - 第 1-7 天循环数字 ID,oracle APEX
- cassandra - 单节点 Cassandra 的行为类似于多节点 Cassandra
- algorithm - 如何计算二元决策图的可达符号状态空间
- html - 阻止显示简化视图提示或在 Chrome 上使用简化视图
- javascript - Pipeable 运算符 rxjs 和 Angular 6
- sbt - 迁移到 sbt 1:如何在编译时运行 Scalastyle