Как протестировать RetryWhen

У меня есть тест для моего блока retryWhen. Он работает правильно при тестировании с помощью эмулятора. У меня также есть тест, который проверяет, проходит ли повторная попытка. Однако иногда мой тест терпит неудачу. Я попытался использовать Scheduler.immediate. Однако это также приводит к провалу теста.

open fun getItem(id: String): Single<Item> {
    return getItemHelper(id)
            .retryWhen { errors ->
                errors.take(1)
                        .filter { it is NotFoundException }
                        .flatMap { _ ->
                            getItemFromServer(id)
                                    .andThen(Observable.just(true))
                        }
            }.subscribeOn(Schedulers.io())
}

Тест:

fun getListOfItem_Retry {
    val objectUnderTest = item[2]
    val testSubscriber : AssertableSubscriber<Item> = actions.getItem(objectUnderTest.id).test()
    testSubscriber.awaitTerminalEvent()

    testSubscriber.assertNoErrors();
    assertTrue(getCalls == 2)
}

В настройках у меня

RxJavaHooks.reset()
RxJavaHooks.setOnIOScheduler({ _ -> Schedulers.immediate()})

И разборка, у меня есть:

RxJavaHooks.reset()

Когда я удаляю крючки, это проходит. Однако иногда тесты терпят неудачу. Как сделать тест стабильным?

Кроме того, я получаю исключение NoSuchElementException без наблюдаемых


person Android Ninja    schedule 11.03.2018    source источник
comment
Проблема заключается в take(1) в логике обработчика повторных попыток, которая завершает внутреннюю последовательность повторных попыток и может завершать внешнюю последовательность. Что вы пытались сделать с первой ошибкой?   -  person akarnokd    schedule 11.03.2018
comment
Я надеялся принять первую ошибку, а затем проверить, действительно ли это, а затем повторить попытку. Я хочу повторить попытку только один раз.   -  person Android Ninja    schedule 11.03.2018
comment
Есть ли способ заставить это пройти с помощью take(1)? @акарнокд   -  person Android Ninja    schedule 11.03.2018


Ответы (1)


Похоже, вы действительно хотите реализовать резервный механизм на случай, если первый источник выйдет из строя. Вы можете просто использовать onErrorResumeNext:

getItemHelper(id)
.onErrorResumeNext({ error -> 
    if (error is NotFoundException) {
        return getItemFromServer(id)
    }
    return Single.error(error)
})
.subscribeOn(Schedulers.io())
.test()
.awaitTerminalEvent()
.assertNoErrors()
person akarnokd    schedule 12.03.2018