Java – RxJava Schedulers.immediate() behavior when unit testing

RxJava Schedulers.immediate() behavior when unit testing… here is a solution to the problem.

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.

Related Problems and Solutions