How to test debounce in RxJava 2?
Welcome to my problem-solving blog series! I will describe here common obstacles, which you can face while developing Android apps, and try to give you simple solutions to overcome these difficulties.
Problem
Let’s say you have a search bar in your app. A common approach of implementing such a feature is by having an observable, which emits input from edit text and using debounce operator from RxJava 2 to not perform searching every time user types in a single letter. Instead, it will wait a certain amount of time between emitting events. Below, you can see a function from SearchRepository
, it’s quite straightforward:
So, as a good citizen of the programming world, we would like to write a unit test for that behavior. First thought? Let’s do something like that:
Simple, isn’t it? Unfortunately, we’ll get this result:
java.lang.AssertionError: Expected: [Item(name=test)] (class: SingletonList), Actual: [] (latch = 1, values = 0, errors = 0, completions = 0)
So, what happened here, is that our testObserver
didn’t get any results, because of the debounce operator which is waiting for certain timeout and assert checks the value immediately. If only we could move time somehow…
Solution
Luckily for us, we can do that! We only need to do 2 things. First, specify on what scheduler our debounce is working by adding it as a third parameter. By default it’s Schedulers.computation
, we can inject it for example into our SearchRepository
.
Second thing, in our test use TestScheduler
and pass it to the SearchRepository
. That way we’re in control of the time! Just call advanceTimeBy
function and advance it by the DEBOUNCE_TIMEOUT
. Et voilà! Now our test will pass smoothly.
In case you wanted to test emitting few events one after another, simply just use advanceTimeBy
function after each one to move the time and assert if the values are correct.
Conclusion
I hope this post will save you some time on googling and going through all these StackOverflow answers. I’m looking forward to your feedback and wait for next posts in my problem-solving blog series! :)