0

I have a test for my retryWhen block. It works properly when tested using the emulator. I also have a test that checks that retry passes. However, sometimes my test fail. I tried using Scheduler.immediate. However, this also makes the test fail.

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())
}

Test:

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

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

In setup, I have

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

And teardown, I have:

RxJavaHooks.reset()

When I remove the hooks, it passes. However, occasionally, the tests fail. How can I get the test to be stable?

Also, I am getting a no Observable Emitted NoSuchElementException

Android Ninja
  • 811
  • 1
  • 6
  • 9
  • The problem is `take(1)` in the retry handler logic, which will complete the inner retry sequence and that can complete the outer sequence. What were you trying to do with the first error? – akarnokd Mar 11 '18 at 17:32
  • I was hoping to take the first error and then check to see if this is valid, then retry. I want to retry only once. – Android Ninja Mar 11 '18 at 18:04
  • Is there a way to get it to pass with take(1)? @akarnokd – Android Ninja Mar 11 '18 at 18:12

1 Answers1

1

Looks like you actually want to implement a fallback mechanism in case the first source fails. You can just use onErrorResumeNext:

getItemHelper(id)
.onErrorResumeNext({ error -> 
    if (error is NotFoundException) {
        return getItemFromServer(id)
    }
    return Single.error(error)
})
.subscribeOn(Schedulers.io())
.test()
.awaitTerminalEvent()
.assertNoErrors()
akarnokd
  • 69,132
  • 14
  • 157
  • 192