Debounce Operator

So debounce is a pretty cool operator in Rx. When you want to emit an item only after a certain amount of time has passed, debounce does that in a pretty simple way:

fun debouncedSource(): Observable<Any> {
    return source().debounce(15, TimeUnit.SECONDS)
}

Testing Debounce

Now that you have solved your problem with debounce, it’s time to write a small test and set it in stone.

@Test
fun “should debounce events every 15 seconds’() {
    // when
    debouncedSource()
        .subscribeOn(testScheduler)
        .subscribe(testObserver)

    testScheduler.advanceTimeBy(15, TimeUnit.SECONDS)
    
    // then
    observer .assertValueCount (1)
    observer .assertNoErrors()
}

Hit ^R to run the test and 💥

java.lang.AssertionError:
Value ounts differ, Expected: 1, Actual: 0

Gotcha

Looks like our sweet little debounce operator runs on its own sweet little scheduler and our TestScheduler wasn’t able to override it. Only took an entire day to figure that out! 🤦‍

Rescue Time

Pass a scheduler to debounce

fun debouncedSource(scheduler: Scheduler): Observable<Any> {
    return source().debounce(15, TimeUnit.SECONDS, scheduler)
}

and use the TestScheduler to test.

@Test
fun “should debounce events every 15 seconds’() {
    // when
    debouncedSource(testScheduler)
        .subscribeOn(testScheduler)
        .subscribe(testObserver)

    testScheduler.advanceTimeBy(15, TimeUnit.SECONDS)
    
    // then
    observer .assertValueCount (1)
    observer .assertNoErrors()
}

Hit ^R to run the test and ʕ•ᴥ•ʔ

1 total, 1 passed
Expected: 1, Actual: 1

If you liked this post, share it and stay tuned for the next one! Read other stuff I’ve written here.