2016-05-22 5 views
1

Ich habe eine einfache TestklasseKotlin: Manuelles Einfügen einer generischen Funktion führt zu einem anderen Ergebnis?

class SimpleClassTest { 

    private fun <T> anyObject(): T { 
     return Mockito.anyObject<T>() 
    } 

    lateinit var simpleObject: SimpleClass 
    @Mock lateinit var injectedObject: InjectedClass 


    @Before 
    fun setUp() { 
     MockitoAnnotations.initMocks(this) 
    } 

    @Test 
    fun testSimpleFunction() { 
     simpleObject = SimpleClass(injectedObject) 
     simpleObject.simpleFunction() 

     verify(injectedObject).settingDependentObject(anyObject()) 
    } 
} 

Es fein und übergeben funktioniert.

Da die private generic anyObject() Funktion nur einmal verwendet wird, so dass ich entscheiden, es zu inlining (manuell), dh die Notwendigkeit dieser Funktion entfernen, wobei ich von

verify(injectedObject).settingDependentObject(anyObject()) 

zu

ändern
verify(injectedObject).settingDependentObject(Mockito.anyObject<DependentClass>()) 

Aber dieser Fehler jetzt als java.lang.IllegalStateException: Mockito.anyObject<DependentClass>() must not be null

Alles, was ich falsch inlining die Funktionsaufruf zu einem direkten stat ement?

Gibt es etwas anders zwischen

private fun <T> anyObject(): T { 
    return Mockito.anyObject<T>() 
} 

und die unter Verwendung von?

Mockito.anyObject<DependentClass>() 
+0

Welche Version von Kotlin und sein Plugin verwenden Sie? – nhaarman

+0

Ich benutze 1.0.1-2. Und wenn ich zu 1.0.2 wechsel, funktioniert es immer noch. – Elye

Antwort

5

Die Quelle für Mockito.anyObject():

/** 
* Matches anything, including null. 
* <p> 
* This is an alias of: {@link #any()} and {@link #any(java.lang.Class)} 
* <p> 
* See examples in javadoc for {@link Matchers} class 
* 
* @return <code>null</code>. 
*/ 
public static <T> T anyObject() { 
    return (T) reportMatcher(Any.ANY).returnNull(); 
} 

Diese Methode setzt einigen internen Zustand für Mockito, und läuft dann weiter null zurückzukehren. Da Sie in Ihrer settingDependentObject()-Methode eine Nicht-Null-Instanz erwarten, schlägt die Laufzeit fehl.


Warum Ihre erste Methode erfolgreich war, bin ich mir jedoch nicht sicher. Casting null bis Tseemed to work a while ago, aber es funktioniert nicht mehr für mich. In diesem Fall kann ich Ihre erste Implementierung auch nicht zum Erfolg führen.

+1

Um dieses Problem zu überwinden, schrieb ich eine kleine [Helferbibliothek] (https://www.github.com/nhaarman/mockito-kotlin). – nhaarman

+0

Hi @nhaarman, großartig, von dir zu hören. Tatsächlich bin ich mir des Null-Fehler-Problems aufgrund der Null-sicheren Anforderung von Kotlin bewusst, und Mockito gab null zurück und fragte mich, wie diese Funktion es für mich funktionierte. Daher stelle ich meine Frage so wie sie ist. Ich habe versucht, die Hilfsbibliothek zu verwenden, aber es gibt ein Problem bei der Verwendung einer OkHttp-Antwort. Ich poste die Frage bei http://stackoverflow.com/questions/37380830/java-lang-reflect-invocationtargetexception-when-using-kotlin-mokito-library, die speziell für Sie ist. (Ich denke, andere werden nicht in der Lage sein, es zu beantworten, da es vielleicht für Ihre Bibliothek spezifisch ist). Danke – Elye

+2

@nhaarman Die erste Methode funktioniert, weil der Compiler nach Aufruf der 'SimpleClassTest.anyObject' -Funktion keine Nullprüfung einfügt. Dieses Verhalten kann später geändert werden, siehe [KT-8135] (https://youtrack.jetbrains.com/issue/KT-8135) – Ilya