【问题标题】:How to unit test RxJava retryWhen如何对 RxJava retryWhen 进行单元测试
【发布时间】:2018-12-21 10:59:03
【问题描述】:

我正在尝试对 RxJava Completable 使用指数退避,并且在我尝试时代码运行良好。所以试图添加一个单元测试来覆盖它,但不确定我们如何在这里测试retryWhen 部分。

    fun makeCall(
        scheduler: Scheduler = scheduler.io()
    ) : Completable {
        val value = "myString"

        return myCompletable(value)
            .retryWhen { errors: Flowable<Throwable> ->
                errors
                    .zipWith(Flowable.range(1, 3))
                    .flatMap { errorRetryPair: Pair<Throwable, Int> ->
                        Flowable.timer(2.toDouble().pow(errorRetryPair.second.toDouble()).toLong(), TimeUnit.SECONDS)
                    }
            }.subscribeOn(scheduler)
    }

有人知道我们如何测试吗? (无法找到很多关于测试的信息以确保 retryWhen 有效)

TIA

【问题讨论】:

    标签: android unit-testing rx-java rx-java2


    【解决方案1】:

    单元测试 RxJava 定时操作最好使用 TestScheduler

    // in your test code
    simulateFailure();
    long firstStepMs = 2_000; // first backoff time in ms
    long epsilon = 40;        // 10ms is too small
    scheduler.advanceTimeBy( firstStepMs - epsilon, TimeUnit.MILLISECONDS );
    // test to see that resubscription has NOT occurred
    scheduler.advanceTimeBy( 2 * epsilon, TimeUnit.MILLISECONDS );
    // test to see that first resubscription HAS occurred
    

    并重复不同的退避时间。推进时钟的粒度取决于您。 epsilon 必须大于 10 毫秒,因为 Java 中的定时器调度是如何工作的;你肯定无法有效地测量任何更短的间隔。

    【讨论】:

    • 谢谢!如果您可以添加一个如何“测试重新订阅”的示例,将会非常有帮助
    • 如果您的观察者链在您重新订阅时没有执行外部可见的操作,您可以在retryWhen() 运算符上方临时添加doOnSubscribe() 运算符到链中。让它增加一个计数器或其他东西,然后检查值。通常,您不会在真实连接上对退避算法进行单元测试,而应该将该部分提取到测试工具中。
    • 是的,已经完成了手动测试并验证它是否按预期工作(如我的帖子中所述),现在正在寻找是否可以使用调度程序进行单元测试?
    • 在单元测试中,您希望测试工具由测试代码控制。在您的情况下,您希望观察者链开头的 Completable 受到控制和检测。例如,您可以使用Completable.create() 来创建一个可完成的功能,该功能将记录订阅并允许您触发错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-07
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 2017-09-19
    • 2012-01-08
    相关资源
    最近更新 更多