Mockito con Kotlin probando la falla asincrónica

Intento aprender a Mockito para mis testings, pero cuando uso Kotlin es más complicado. Quiero probar una function en mi presentador que, cuando se invoca, busca una list de objects del repository de forma asincrónica y activa onSuccess / onError desde un oyente. Después de eso, el presentador le dice a la vista que haga lo que sea necesario de acuerdo con la callback.

Aquí está el código de testing:

@Mock lateinit var view: CategoriesActivityContract.View @Mock lateinit var repository: CategoriesRepository @Before fun setUp() { MockitoAnnotations.initMocks(this) } @Test fun shouldPassCategoriesToView2() { `doAnswer`({ it: InvocationOnMock? -> (it!!.arguments[0] as CategoriesRepository.OnGetCategoriesListener).onSuccess(DUMMY_CATEGORIES) null }).`when`(repository).getCategoriesAsync(any(CategoriesRepository.OnGetCategoriesListener::class.java)) val presenter: CategoriesActivityPresenter = CategoriesActivityPresenter(repository) presenter.bindView(view) presenter.loadCategories() `verify`(view).displayCategories(DUMMY_CATEGORIES) } 

Ese es el código probado:

 override fun loadCategories() { repository.getCategoriesAsync(object: CategoriesRepository.OnGetCategoriesListener { override fun onSuccess(categories: List<Category>) { if (!categories.isEmpty()) { view?.displayCategories(categories) } else { view?.displayNoCategoriesError() } } override fun onError(message: String?) { view?.displayNoCategoriesError() } }) } 

Y la testing falla con este post de error:

 java.lang.IllegalStateException: any(CategoriesRepository…riesListener::class.java) must not be null at com.boyukliev.verseattack.ui.categories.CategoriesActivityPresenterTest.shouldPassCategoriesToView2(CategoriesActivityPresenterTest.kt:60) 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.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:68) at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:74) at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39) at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:161) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84) 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 com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Misplaced or misused argument matcher detected here: -> at com.boyukliev.verseattack.ui.categories.CategoriesActivityPresenterTest.shouldPassCategoriesToView2(CategoriesActivityPresenterTest.kt:60) You cannot use argument matchers outside of verification or stubbing. Examples of correct usage of argument matchers: when(mock.get(anyInt())).thenReturn(null); doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject()); verify(mock).someMethod(contains("foo")) This message may appear after an NullPointerException if the last matcher is returning an object like any() but the stubbed method signature expect a primitive argument, in this case, use primitive alternatives. when(mock.get(any())); // bad use, will raise NPE when(mock.get(anyInt())); // correct usage use Also, this error might show up because you use argument matchers with methods that cannot be mocked. Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode(). Mocking methods declanetworking on non-public parent classes is not supported. at org.mockito.internal.runners.DefaultInternalRunner$1$1.testFinished(DefaultInternalRunner.java:58) at org.junit.runner.notification.SynchronizedRunListener.testFinished(SynchronizedRunListener.java:56) at org.junit.runner.notification.RunNotifier$7.notifyListener(RunNotifier.java:190) at org.junit.runner.notification.RunNotifier$SafeNotifier.run(RunNotifier.java:72) at org.junit.runner.notification.RunNotifier.fireTestFinished(RunNotifier.java:187) at org.junit.internal.runners.model.EachTestNotifier.fireTestFinished(EachTestNotifier.java:38) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:331) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:68) at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:74) at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39) at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:161) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84) 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 com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) 

Mockito.any(Class<T>) devuelve null ( [1] , [2] ), que no es aceptado por el método getCategoriesAsync .
Puede usar la biblioteca Mockito-Kotlin que no 'devuelve valores nulos' para solucionar este problema.