RxJava Schedulers.immediate() behavior when unit testing
I’m trying to write tests for DAO objects that use a Reactive interface. I have a table with recipes and I want to test that when I insert data into the table, subscribers receive a list with recipes.
I’m using the TestSubscriber class and performing assertions on that class. My simple test looks like this:
@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)
}
The problem is asserting that testSubscriber.assertValueCount(1)
failed because no items were emitted. But when I insert this line above
testSubscriber.awaitTerminalEvent(500, TimeUnit.MILLISECONDS),
test successful. My observable doesn’t emit terminal events, so execution times out, but while waiting, onNext is called with a recipe list.
My getRecipes method:
fun getRecipes(): Observable<List<Recipe>> {
return query(SELECT("*")
. FROM(Recipe.TABLE_NAME)
. ORDER_BY(Recipe.COL_NAME))
.run()
.mapToList(RecipeMapper.MAPPER)
}
How is this possible? I think when I use Schedulers.immediate(), the operation will execute on the same thread and my TestSubscriber receives the event. If not, how should I write this test to be successful? I want to test if onNext is called and I don’t want to insert artificial sleep commands in between.
Solution
The problem is that I use the library SqlBrite with the additional framework SqlBrite-Dao. SqlBrite is observing queries for a specific scheduler
, using Schedulers.io()
when no queries are provided to SqlBrite-Dao’s DaoManager
. The solution is to provide a scheduler or apply RxJavaPlugins to DaoManager.Builder
and return Schedulers.immediate()
as all schedulers
.