2016-05-21 5 views
6

Mein Code wie unten Mokito ANYOBJECT() mit, was sich auf die Lösung in https://stackoverflow.com/a/30308199/3286489Parameter als nicht-null angegeben ist null, wenn sie auf Kotlin Funktion

import org.mockito.Mock 
import org.mockito.Mockito 
import org.mockito.MockitoAnnotations 
import org.mockito.Mockito.* 

class SimpleClassTest { 

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

    private fun <T> uninitialized(): T = null as T 
    lateinit var simpleObject: SimpleClass 
    @Mock lateinit var injectedObject: InjectedClass 


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

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

     verify(injectedObject).settingDependentObject(anyObject()) 

    } 
} 

ich noch die folgenden Fehler haben

java.lang.IllegalArgumentException: Parameter specified as non-null is null: method my.package.InjectedClass.settingDependentObject, parameter dependentObject 

Habe ich etwas vermisst?

AKTUALISIERT Unten ist der Code getestet (einfachste Form und Arbeits)

class SimpleClass(val injectedClass: InjectedClass) { 

    fun simpleFunction() { 
     injectedClass.settingDependentObject(DependentClass(Response.Builder().build())) 
    } 
} 

open class DependentClass(response: Response) { 

} 

open class InjectedClass() { 
    lateinit var dependentObject: DependentClass 

    fun settingDependentObject(dependentObject: DependentClass) { 
     this.dependentObject = dependentObject 
    } 
} 

Antwort

9

standardmäßig Kotlin classes and members are final. Mockito cannot mock final classes or methods. Wenn Sie also schreiben:

verify(injectedObject).settingDependentObject(anyObject()) 

die reale Implementierung genannt wird, die nicht null-Argument erfordert.

Um dies zu beheben, dass entweder Klasse öffnen und Methode oder, noch besser, SimpleClass ändern, um eine Schnittstelle als Konstruktorargument zu akzeptieren und die Schnittstelle statt verspotten.

+0

Meine injectObject-Klasse ist bereits eine offene Klasse. Das settingDependentObject erfordert ein Nicht-Null-Objekt, aber AnyObject() gibt null zurück. Deshalb dachte ich, die Lösung in http://stackoverflow.com/a/30308199/3286489 würde mir helfen, das Null-Problem zu überwinden. Aber es funktioniert immer noch nicht. – Elye

+0

@Elye fügen Sie der Frage – miensol

+0

bitte die Quelle 'InjectedClass' hinzu. Fügen Sie die zu testende Klasse zu dem obigen Update hinzu. Vielen Dank! – Elye

1

Es gibt ein Projekt speziell, um mit Kotlin "standardmäßig geschlossen" in Komponententests mit Mockito zu helfen. Für JUNIT können Sie die kotlin-testrunner verwenden, die eine einfache Möglichkeit ist, jeden Kotlin-Test automatisch zu testen, wenn sie vom Klassenlader geladen werden. Die Verwendung ist einfach, fügen Sie einfach eine Anmerkung von @RunWith(KotlinTestRunner::class), zum Beispiel:

@RunWith(KotlinTestRunner::class) 
class MyKotlinTestclass { 
    @Test 
    fun test() { 
    ... 
    } 
} 

Diese gründlich im Artikel behandelten Never say final: mocking Kotlin classes in unit tests

Diese Ihren Anwendungsfall in einer automatischen Art und Weise behandelt, indem alle Klassen sein verspottet, dass sonst nicht erlaubt wäre.