2017-03-26 4 views
0

Ich versuche Mockito für meine Tests zu lernen, aber mit Kotlin ist es komplizierter. Ich möchte eine Funktion in meinem Presenter testen, die beim Aufruf eine Liste von Objekten asynchron aus dem Repository holt und onSuccess/onError von einem Listener auslöst. Danach teilt der Moderator der Ansicht mit, dass er gemäß dem Callback alles Notwendige tun soll.Mockito mit Kotlin asynchronen Fehler testen

Hier ist der Testcode:

@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) 
} 

Das ist der getesteten Code:

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() 
     } 
    }) 
} 

Und der Test nicht mit dieser Fehlermeldung:

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 declared 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) 

Antwort

1

Mockito.any(Class<T>) kehrt null ([1], [2]), was nicht der Fall ist akzeptiert durch die getCategoriesAsync Methode.
Sie können die Mockito-Kotlin-Bibliothek verwenden, die keine Nullwerte zurückgibt, um dieses Problem zu beheben.

+0

Haftungsausschluss: Ich bin der Autor von Mockito-Kotlin. – nhaarman

Verwandte Themen