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)
))
}
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.doAnswer
is the way to go.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()