【问题标题】:How to test RetryWhen如何测试 RetryWhen
【发布时间】:2018-03-12 18:16:44
【问题描述】:

我对我的 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()

当我移除钩子时,它通过了。但是,有时测试会失败。我怎样才能使测试稳定?

另外,我得到一个 no Observable Emitted NoSuchElementException

【问题讨论】:

  • 问题在于重试处理逻辑中的take(1),它将完成内部重试序列并且可以完成外部序列。你想对第一个错误做什么?
  • 我希望得到第一个错误,然后检查它是否有效,然后重试。我只想重试一次。
  • 有没有办法让它通过 take(1)? @akarnokd

标签: kotlin rx-java nosuchelementexception retrywhen


【解决方案1】:

看起来您实际上想要实现一个回退机制,以防第一个源失败。你可以使用onErrorResumeNext:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-22
    • 2019-05-20
    • 2018-01-14
    • 1970-01-01
    • 2019-01-20
    • 1970-01-01
    • 2018-12-26
    相关资源
    最近更新 更多