I'm writing a unit test. Below is my code. The architecture is MVVM using Dagger2. I'm calling the login function residing in the LoginViewModel, which is notifying the getLoginState function. The error I'm getting is:
Error:
io.mockk.MockKException: no answer found for: Observer(#8).onChanged(Success(data=))
at io.mockk.impl.stub.MockKStub.defaultAnswer(MockKStub.kt:90)
LoginViewModelClass:
fun logIn(phone: String, phoneCode: String) {
loginState.value = Outcome.success("")
}
fun getLoginState(): LiveData<Outcome<String>> = loginState
LoginViewModelTest class:
@RelaxedMockK
var SUT: LoginViewModel? = null
@Mock
var loginInteractor: LoginInteractor? = null
@Mock
var textValidator: TextValidator? = null
@Mock
var textProvider: TextProvider? = null
@Mock
var blinkUserPreferences: BlinkUserPreferences? = null
@get:Rule
var rule: TestRule = InstantTaskExecutorRule()
@RelaxedMockK
var mockObserver: Observer<Outcome<String>>? = null
@Before
fun setUp() {
MockKAnnotations.init(this, relaxUnitFun = true)
SUT = spyk(
LoginViewModel(
mockk<LoginInteractor>(),
mockk<TextValidator>(relaxed = true),
mockk<TextProvider>(),
mockk<BlinkUserPreferences>()))
mockObserver = mockk<Observer<Outcome<String>>>()
SUT!!.getLoginState().observeForever(mockObserver!!)
}
@Test
fun logIn() {
//Arrange
every {SUT!!.getLoginState().value} returns Outcome.success("")
//Act
SUT!!.logIn("89989676","89998")
//Assert
verify() { mockObserver!!.onChanged(Outcome.success("abc")) }
}
Question: In verification, why onChanged method is not being called, or what does it mean that no answer found for Observer().onChanged, how can I notify my onChanged method so I can verify it?
After watching this: https://mockk.io/#answers. It says
I just posted this:
in the following test function and it worked.
According to my understanding, if you
mockka function, and you want to use its particular function you must use theeveryexpression to tell framework that it willanswer, because framework needs to know that it needs to answer something.And if you want that all behaviour functions should also be added with mock with their implementation then you must
spykyour class so that it gets the behaviour as well and then you can easily use the function without using expressionevery.Please note that
everyexpression is used for many cases like to get a mocked result out of that function, or just need to tell the framework that this function shouldanswersthis.Please correct me through comments if I'm wrong, Ill update it.