Debounce ignoring timeout in unit tests

Viewed 708

I have this method to fetch search result from api

public void fetchSearchResults(Observable<String> searchObservable) {
    searchObservable
        .filter(search -> !TextUtils.isEmpty(search))
        .debounce(700, TimeUnit.MILLISECONDS)
        .observeOn(AndroidSchedulers.mainThread())
        .doOnNext(search -> getView().showLoader)
        .switchMap(search -> apiService.fetchSearchResults(search)) //Api call is executed on an io scheduler
        .subscribe(consumer, errorConsumer);
}

and I wrote this JUnit test for this method:

@Test
public void fetchSearchResultsTest() {
    TestScheduler testScheduler = new TestScheduler();
    Observable<String> nameObservable = Observable.just("","FA")
            .concatMap(search -> Observable.just(search).delay(100,
                           TimeUnit.MILLISECONDS, testScheduler));
    testScheduler.advanceTimeBy(100, TimeUnit.MILLISECONDS);
    verify(view, never()).showLoader();
    
    testScheduler.advanceTimeBy(100, TimeUnit.MILLISECONDS);
    verify(view, never()).showLoader();
}

But the test fails on the last verify statement with message

org.mockito.exceptions.verification.NeverWantedButInvoked

view.showLoader();

I have tried passing a TestScheduler to the debounce operator and setting the default computation scheduler as a TestScheduler through RxJavaPlugins but the result does not change, the test still fails.

If the test is failing then that would mean that the debounce operator is sending the event right through it ignoring timeout passed in it's arguments. I don't know if this correct but this is as far I understand. So, my question is how can I fix this test and control the events from the debounce operator like I'm doing with the source observable with TestSchedulers?

1 Answers

Your test is failing because of the onCompleted() that occurs when the second item is emitted. The documentation says that debounce() will issue the final item immediately that it receives onCompleted().

To make your test work, either concatenate an Observable.never(), or add more items into the pipeline.

Here is an article on using debounce for doing auto-completion.

Related