Android Mockito-Kotlin error – “Actually, there were zero interactions with this mock”

Issue

The following is the test code for my ViewModel class. My app architecture is based on MVI. Basically, I’m trying to mock my repo and state classes. In the test function I wrote below, I’m trying to check if state is changed in correct order when I successfully load a news list from an API.

class NewsListViewModelTest {
    //...

    @get:Rule
    val testSchedulerRule  RxTestSchedulerRule()

    private lateinit var testSubject: NewsListViewModel    

    private val loadingState  NewsListState(state  State.LOADING)

    private val newsRepo  mock<NewsRepository>()
    private val observer  mock<Observer<NewsListState>>()

    @Before
    fun setUp() {
        testSubject  NewsListViewModel(newsRepo)
        testSubject.observableState.observeForever(observer)
    }

    @Test
    fun `Given news list successfully loaded, when action LoadNewsList is received, then state contains news list`() {
        // GIVEN
        val newsList  listOf(News("title", "description", Date(), "image"))
        val successState  NewsListState(newsList  newsList, state  State.DATA)

        whenever(newsRepo.loadAll("keyword", 1, 1))
            .thenReturn(Observable.just(newsList))

        // WHEN
        testSubject.dispatch(NewsListAction.LoadNewsList("keyword"))
        testSchedulerRule.triggerActions()

        // THEN
        inOrder(observer) {
            verify(observer).onChanged(loadingState)
            verify(observer).onChanged(successState)
        }
        verifyNoMoreInteractions(observer)
    }
}

However, when I run this test, I’m getting the following error in the first line inside inOrder(observer){ ... }:

Wanted but not invoked:
observer.onChanged(
    NewsListState(newsList[], stateLOADING, errorMessage)
);
-> at [packagename].NewsListViewModelTest.Given news list failed to load, when action LoadNewsList is received, then state contains error(NewsListViewModelTest.kt:77)
Actually, there were zero interactions with this mock.

And these are my testing dependencies:

testImplementation 'junit:junit:4.12'
testImplementation 'androidx.arch.core:core-testing:2.1.0'
testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0'

What might be the reason of this error?

Edit — My RxTestSchedulerRule class:

class RxTestSchedulerRule(private val testScheduler: TestScheduler  TestScheduler()) : Scheduler(),
    TestRule {
    override fun apply(base: Statement, description: Description?): Statement {
        RxJavaPlugins.setIoSchedulerHandler { testScheduler }
        RxJavaPlugins.setComputationSchedulerHandler { testScheduler }
        RxJavaPlugins.setNewThreadSchedulerHandler { testScheduler }
        RxJavaPlugins.setSingleSchedulerHandler { testScheduler }
        RxAndroidPlugins.setInitMainThreadSchedulerHandler { Schedulers.trampoline() }
        return base
    }

    override fun createWorker()  testScheduler.createWorker()

    fun triggerActions()  testScheduler.triggerActions()
}

Edit 2 — My dispatch function:

fun dispatch(?) {
     newsRepository.loadAll(keyword  it.keyword, 
                            pageSize  pageSize, 
                            page  page)
                   .subscribeOn(Schedulers.io()) 
                   .map<NewsListChange> { newsList -> 
                         NewsListChange.Data(newsList) } 
                  .defaultIfEmpty(NewsListChange.Data(emptyList())) 
                  .onErrorReturn { throwable -> 
                       NewsListChange.Error(throwable) } 
                  .startWith(NewsListChange.Loading)
}

Solution

please try instead of this line

whenever(newsRepo.loadAll("keyword", 1, 1))
            .thenReturn(Observable.just(newsList))

put

whenever(newsRepo.loadAll(anyString(), anyInt(), anyInt()))
            .thenReturn(Observable.just(newsList))

Answered By – Lena Bru

Leave a Comment