Search code examples
androidkotlinmockitoandroid-espressoui-testing

doNothing() does not work when i want to mock data and test UI Fragment


I am going to test fragment with Espresso then i want to mock viewmodels and members.

In my viewModel i have a void function like this :

fun getLoginConfig() {
    viewModelScope.launchApiWith(_loginConfigLiveData) {
       repository.getLoginConfig()
    }
}

In test fragment when we call getLoginConfig() from viewModel i want to mock it with doNothing() but i faced with this error :

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here


E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod();
Hints:
 1. missing thenReturn()
 2. you are trying to stub a final method, which is not supported
 3. you are stubbing the behaviour of another mock inside before 'thenReturn' instruction is completed

At this line on testFragmentClass :

   @Before
    fun setUp() {
        //logOut


        mockVm = mock(SplashVM::class.java)

        loadKoinModules(module {
            single {
                mockVm
            }
        })
}




   doNothing().`when`(mockVm.getLoginConfig()).let {
       mockVm.loginConfigLiveData.postValue(Resource.Success(
           LoginConfigResponse(
               listOf("1"),1,1,"1",true)
       ))
   }

Solution

  • A few things:

    • doNothing just does nothing, which is unnecessary for void methods on a mock. It's the default behavior. You only want doNothing for spies or already-stubbed mocks.
    • If you want something specific to happen in response to a call on a mock, doAnswer is the way to go.
    • In doVerb syntax, Mockito expects that there is only a variable there; the expression should not call a method on a mock, or else Mockito thinks you've lost interest and throws UnfinishedStubbingException.

    Therefore your fix looks like:

    doAnswer {
      mockVm.loginConfigLiveData.postValue(Resource.Success(
        LoginConfigResponse(
          listOf("1"),1,1,"1",true)
      ))
    }.`when`(mockVm).getLoginConfig()