2017-05-20 1 views
1

Meine Kotlin-Klasse kompiliert und läuft auf einem Emulator ohne ein Problem. Aber wenn ich es teste, sagt Android Studio, dass die Klasse nicht gefunden wird.NoClassDefFoundError auf Kotlin Klasse in JUnit Test zur Laufzeit

Hier ist die Kotlin Klasse und ein Beispiel für die Verwendung es:

// Product.kt 
data class Product(
    val id: Int, 
    val name: String, 
    val manufacturer: String) 

// MainActivity.java 
public class MainActivity extends Activity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     Product product = new Product(0, "foo", "bar"); 
     TextView textView = findViewById(R.id.textView); 
     textView.setText(product.getName()); 
    } 
} 

enter image description here

jedoch, wenn ich einen JUnit-Test für die Klasse Kotlin schreiben:

// ProductTest.java 
public class ProductTest { 
    @Test 
    public void getName() throws Exception { 
     Product p = new Product(0, "foo", "bar"); 
     assertThat(p.getName(), equalTo("foo")); 
    } 
} 

Android Studio erstellt die Code, aber weigert sich, den Test auszuführen:

java.lang.NoClassDefFoundError: com/example/Product 

    at com.example.ProductTest.getName(ProductTest.java:15) 
    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.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.junit.runner.JUnitCore.run(JUnitCore.java:137) 
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) 
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51) 
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) 
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) 
    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.AppMainV2.main(AppMainV2.java:131) 
Caused by: java.lang.ClassNotFoundException: com.example.Product 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 
    ... 28 more 

Hier kommt der dependencies Abschnitt in der Modulebene build.gradle:

dependencies { 
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" 
    testCompile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" 
    testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" 
    testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version" 
    testCompile 'junit:junit:4.12' 
} 

Was habe ich falsch gemacht?

+0

Mögliche Duplikate von [Android Studio 3.0 Canary 1: Kotlin-Tests oder Java-Tests zu Kotlin-Klassen schlagen fehl] (http://stackoverflow.com/questions/44079918/android-studio-3-0-canary-1-kotlin -tests-or-java-tests-bezogen auf-kotlin-clas) – jsc0

Antwort

1

Dies funktioniert derzeit nicht mit den neuesten Tools. Dafür gibt es im Jetbrains Tracker einen open issue.

1

Die Lösung besteht darin, eine neue Aufgabe in der Datei build.gradle zu erstellen.

android { 
    task copyTestClasses(type: Copy) { 
     from "build/tmp/kotlin-classes/debugUnitTest" 
     into "build/intermediates/classes/debug" 
    } 

Dann fügen Sie diese Aufgabe auf den „Vor dem Start eines“ -Abschnitt der Testlauf-Konfiguration.

enter image description here

+0

Ich musste zwei Aufgaben für Klassen und Testklassen erstellen. – Sah

1

ist dies eine offene Frage, ich denke, es bald behoben werden:

task copyTestClasses(type: Copy) { 
    from "build/tmp/kotlin-classes/debugUnitTest" 
    into "build/intermediates/classes/debug" 
} 

task copySdkClasses(type: Copy) { 
    from "build/tmp/kotlin-classes/debug" 
    into "build/intermediates/classes/debug" 
} 
:

https://youtrack.jetbrains.com/issue/KT-17951

https://issuetracker.google.com/issues/38454212

Inzwischen Sie die folgende Abhilfe verwenden können

Fügen Sie es Ihrer Gradle Datei (nach android {...} Abschnitt)

Danach werden die Tests Konfiguration öffnen und fügen Sie neue „vor dem Start“ Schritt, der diese Aufgaben ausführt:

enter image description here

enter image description here

enter image description here

+0

Danke, das hat für mich funktioniert –

Verwandte Themen