Reputation: 2417
I have set up my ViewModel
to repeat an API call endlessly this way:
useCase.fireAPICall(params)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.repeat()
.delay(1, TimeUnit.SECONDS)
.subscribe(::onSuccess, ::onFailed)
In my unit tests, I'm trying to mock the API call and check whether or not the LiveData
inside the ViewModel
(updated in the ::OnSuccess
method) is updated accordingly.
Working unit test that tests a failure:
val error = Throwable("")
// Arrange
Mockito.`when`(repo.apiCall(params))
.thenReturn(Single.error(error))
// Act
viewModel.init()
// Verify
Mockito.verify(postDetailsViewStateObserver)
.onChanged(Error(error))
** Non-working:** f instead, I try to mock a valid response from that API call with:
// Arrange
Mockito.doReturn(Single.just(Success(result, list)))
.`when`(repo).apiCall(params)
Then the ViewModel
repeat()
generates an endless loop which blocks my unit test without completing it ever.
Question: how can we test a repeat()
situation by checking just the first thing emitted on that observable?
Upvotes: 1
Views: 652
Reputation: 161
You need to provide a scheduler for delay
to take advantage of the time in test so e.g.:
val testScheduler = TestScheduler()
RxJavaPlugins.setComputationSchedulerHandler { testScheduler }
And after that call testScheduler.advanceTimeBy(1, TimeUnit.SECONDS)
so you will move forward by one second. To make it work you should probably also change the order, delay
should be before the repeat
.
You need to setComputationSchedulerHandler
as delay
is by default uses this scheduler.
Upvotes: 1