2016-10-26 2 views
3

Я пытаюсь написать тест для моего объекта DAO, который использует реактивный интерфейс. У меня есть таблица с рецептами, и я хочу проверить, что, когда я вставляю данные в эту таблицу, абонент получает список с рецептами.RxJava Schedulers.immediate() поведение во время модульного тестирования

Я использую класс 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), тест проходит успешно. Мое наблюдаемое не излучает терминальное событие, и поэтому выполняется тайм-аут, но тем временем ожидания, 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, и я не хочу вставлять искусственные команды сна между ними.

+0

Я предполагаю, что у вас есть некоторые зависящие от времени операции в 'getRecipes' (например,' delay', 'timer',' interval' и т. Д.) Или использовать 'observOn' или' subscribeOn' с другим планировщиком. В таком случае Планировщик в вашем тесте не будет применяться. Не могли бы вы показать нам свой 'РецептДао'? –

+0

Привет, я редактировал вопрос и добавил мой метод getRecipes. Я не изменяю планировщик подписки или наблюдения, и я не выполняю никаких временных операций. – Billda

+0

Метод 'run()' выглядит подозрительно для меня - он возвращает 'Observable'? Или 'mapToList' возвращает' Observable'? Если да, возможно, один из этих методов объявит собственный планировщик? –

ответ

3

Проблема заключалась в том, что я использовал библиотеку SqlBrite с дополнительной структурой SqlBrite-Dao. SqlBrite наблюдает за запросом на конкретный планировщик, и когда ни один не был предоставлен DaoManager из SqlBrite-Dao, использовался Schedulers.io(). Решение состоит в том, чтобы предоставить планировщику DaoManager.Builder или применить RxJavaPlugins и вернуть Schedulers.immediate() как все планировщики.

Смежные вопросы