【发布时间】:2016-10-26 12:06:11
【问题描述】:
我正在尝试为使用响应式接口的 DAO 对象编写测试。我有一个带有食谱的表,我想测试当我向该表插入数据时,订阅者会收到带有食谱的列表。
我正在使用 TestSubscriber 类并在该类上执行断言。我的简单测试如下所示:
@Test
fun testSubscriber() {
insertItem()
val testSubscriber = TestSubscriber.create<List<Recipe>>()
recipeDao
.getRecipes()
.subscribeOn(Schedulers.immediate())
.subscribe(testSubscriber)
testSubscriber.assertNoErrors()
testSubscriber.assertNoTerminalEvent()
testSubscriber.assertNotCompleted()
testSubscriber.assertValueCount(1)
assertEquals(1, testSubscriber.onNextEvents[0].size)
}
问题是断言testSubscriber.assertValueCount(1) 失败,因为没有发出任何项目。但是当我在上面插入这一行时
testSubscriber.awaitTerminalEvent(500, TimeUnit.MILLISECONDS),测试成功。我的 observable 不会发出终端事件,因此会执行超时,但在等待的同时,使用配方列表调用了 onNext。
我的 getRecipes 方法:
fun getRecipes(): Observable<List<Recipe>> {
return query(SELECT("*")
.FROM(Recipe.TABLE_NAME)
.ORDER_BY(Recipe.COL_NAME))
.run()
.mapToList(RecipeMapper.MAPPER)
}
这怎么可能?我以为当我使用 Schedulers.immediate() 时,操作将在同一个线程上执行,并且我的 TestSubscriber 接收事件。如果没有,我应该如何编写此测试以使其成功?我想测试是否调用了 onNext,并且我不想在两者之间插入人工睡眠命令。
【问题讨论】:
-
我假设您在
getRecipes中有一些与时间相关的操作(如delay、timer、interval等)或使用observeOn或subscribeOn与不同的调度器。在这种情况下,您的测试中的调度程序将不会被应用。你能告诉我们你的RecipeDao吗? -
嗨,我编辑了问题并添加了我的 getRecipes 方法。我没有修改订阅或观察调度程序,也没有做任何时间敏感的操作。
-
方法
run()在我看来很可疑 - 它是否返回Observable?还是mapToList返回Observable?如果是这样,也许其中一种方法声明了自己的调度程序? -
好吧,我解决了 :) 我正在使用库 SqlBrite,它正在观察特定调度程序的查询。如果没有选择调度程序,则使用 Schedulers.io()。当我将其切换到 Schedulers.immediate() 时,测试成功了。谢谢!
-
哦,我明白了。很高兴知道!
标签: java android unit-testing rx-java kotlin