Hi guys. I am trying to learn unit tests using Kotlin using a google github sample as a base . My code is very similar, but I can't get one of my more basic tests to work (and I don't understand it).
My main question is that the test is running sendResultToUI(),
@Test
public void sendResultToUI() {
MutableLiveData<Resource<User>> foo = new MutableLiveData<>();
when(userRepository.loadUser("foo")).thenReturn(foo);
Observer<Resource<User>> observer = mock(Observer.class);
userViewModel.getUser().observeForever(observer);
userViewModel.setLogin("foo");
verify(observer, never()).onChanged(any(Resource.class));
User fooUser = TestUtil.createUser("foo");
Resource<User> fooValue = Resource.success(fooUser);
foo.setValue(fooValue);
verify(observer).onChanged(fooValue);
reset(observer);
}
From what I can say, he says:
- a) When called
loadUser("foo"), instead of executing the function, just return a new guy with live data named foo. - b) Observe current data
userViewModel.getUser() - c) A call
setLogin("foo")that runs the current data and callsloadUser("foo") - d) Verify that the watcher before
getUser()that we created earlier was never started by any instance of the resource - e) foo, ,
getUser() observer
, , d). :
java.lang.IllegalStateException: ArgumentMatchers.any(T::class.java) must not be null
, , onChanged . , , , - setLogin() c) switchMap, , , userRepositiory.loadUser(), getUser(), ( ). loadUser() foo, a). , - , !
: unit test, , , ( , , , , !)
@Test
fun `send result to UI`(){
val foo = MutableLiveData<Resource<Member>>()
`when`(interactor.callServerLoginRepo(email, password)).thenReturn(foo)
val observer: Observer<Resource<Member>> = mock()
loginViewModel.member.observeForever(observer)
loginViewModel.setLoginCredentials(email, password)
verify<Observer<Resource<Member>>>(observer, never()).onChanged(any(Resource::class.java) as Resource<Member>)
val fooUser = TestUtil.createMember(email)
val fooValue = Resource.success(fooUser)
foo.setValue(fooValue)
verify<Observer<Resource<Member>>>(observer).onChanged(fooValue)
reset<Observer<Resource<Member>>>(observer)
}
MockitoHelpers.kt
fun <T> any(type: Class<T>): T = Mockito.any<T>(type)
:
kotlin.TypeCastException: null cannot be cast to non-null type app.core.sdk.data.remote.response.Resource<app.core.sdk.data.model.db.Member>
at app.core.sdk.ui.login.LoginViewModelTest.send result to UI(LoginViewModelTest.kt:114)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
2, :
, , any(), any(), , . Mockito-Kotlin , any, I, , :
inline fun <reified T : Any> any() = Mockito.any(T::class.java) ?: createInstance<T>()
, , Mockito.any(), , Kotlin .
val foo = MutableLiveData<Resource<Member>>()
`when`(interactor.callServerLoginRepo(email, password)).thenReturn(foo)
val observer: Observer<Resource<Member>> = mock()
loginViewModel.member.observeForever(observer)
loginViewModel.setLoginCredentials(email, password)
verify(observer, never()).onChanged(any())
val fooUser = TestUtil.createMember(email)
val fooValue = Resource.success(fooUser)
foo.value = fooValue
verify(observer).onChanged(fooValue)
reset(observer)