it-swarm.com.de

Kotlin und neue ActivityTestRule: Die @Rule muss öffentlich sein

Ich versuche, einen UI-Test für meine Android= App in Kotlin durchzuführen. Da das neue System ActivityTestRule verwendet, kann ich es nicht zum Laufen bringen: Es wird korrekt kompiliert und zur Laufzeit erhalte ich:

Java.lang.Exception: The @Rule 'mActivityRule' must be public.
    at org.junit.internal.runners.rules.RuleFieldValidator.addError(RuleFieldValidator.Java:90)
    at org.junit.internal.runners.rules.RuleFieldValidator.validatePublic(RuleFieldValidator.Java:67)
    at org.junit.internal.runners.rules.RuleFieldValidator.validateField(RuleFieldValidator.Java:55)
    at org.junit.internal.runners.rules.RuleFieldValidator.validate(RuleFieldValidator.Java:50)
    at org.junit.runners.BlockJUnit4ClassRunner.validateFields(BlockJUnit4ClassRunner.Java:170)
    at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.Java:103)
    at org.junit.runners.ParentRunner.validate(ParentRunner.Java:344)
    at org.junit.runners.ParentRunner.<init>(ParentRunner.Java:74)
    at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.Java:55)
    at Android.support.test.internal.runner.junit4.AndroidJUnit4ClassRunner.<init>(AndroidJUnit4ClassRunner.Java:38)
    at Android.support.test.runner.AndroidJUnit4.<init>(AndroidJUnit4.Java:36)
    at Java.lang.reflect.Constructor.constructNative(Native Method)
    at Java.lang.reflect.Constructor.newInstance(Constructor.Java:417)
    at Android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder.buildAndroidRunner(AndroidAnnotatedBuilder.Java:57)
    at Android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder.runnerForClass(AndroidAnnotatedBuilder.Java:45)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.Java:57)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.Java:29)
    at org.junit.runner.Computer.getRunner(Computer.Java:38)
    at org.junit.runner.Computer$1.runnerForClass(Computer.Java:29)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.Java:57)
    at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.Java:98)
    at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.Java:84)
    at org.junit.runners.Suite.<init>(Suite.Java:79)
    at org.junit.runner.Computer.getSuite(Computer.Java:26)
    at Android.support.test.internal.runner.TestRequestBuilder.classes(TestRequestBuilder.Java:691)
    at Android.support.test.internal.runner.TestRequestBuilder.build(TestRequestBuilder.Java:654)
    at Android.support.test.runner.AndroidJUnitRunner.buildRequest(AndroidJUnitRunner.Java:329)
    at Android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.Java:226)
    at Android.app.Instrumentation$InstrumentationThread.run(Instrumentation.Java:1584)

So habe ich mActivityRule deklariert:

RunWith(javaClass<AndroidJUnit4>())
LargeTest
public class RadisTest {

    Rule
    public val mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(javaClass<MainActivity>())

   ...
}

Es ist bereits öffentlich: /

233
Geob-o-matic

Mit JUnit können Regeln über ein Testklassenfeld oder eine Getter-Methode bereitgestellt werden.

Was Sie kommentiert haben, ist in Kotlin eine Eigenschaft , die JUnit jedoch nicht erkennt.

So können Sie eine JUnit-Regel in Kotlin angeben:

Durch eine kommentierte Getter-Methode

ab M1 , der Anmerkungsprozessor nterstützt Anmerkungsziele . Wenn du schreibst

@Rule
public val mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(javaClass<MainActivity>())

die Annotation verwendet jedoch standardmäßig das Ziel property (für Java nicht sichtbar).

Sie können den Eigenschafts-Getter jedoch mit Anmerkungen versehen, der ebenfalls öffentlich ist und somit die JUnit-Anforderungen für einen Regel-Getter erfüllt:

@get:Rule
public val mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(javaClass<MainActivity>())

Alternativ können Sie die Regel mit einer Funktion anstelle einer Eigenschaft definieren (manuell dasselbe Ergebnis wie mit @get:Rule Erzielen).

Durch ein kommentiertes öffentliches Feld

Kotlin ermöglicht es seit dem Beta-Kandidaten auch, Eigenschaften für Felder in der JVM deterministisch zu kompilieren. In diesem Fall gelten die Anmerkungen und Modifizierer für das generierte Feld. Dies geschieht mit Kotlins @JvmField Eigenschaftsanmerkung als beantwortet von @jkschneider .


Randnotiz: Stellen Sie sicher, dass Sie der Annotation Rule ein @ - Zeichen voranstellen, wie es jetzt ist die einzige unterstützte Syntax für Annotationen , und vermeiden Sie @publicField wie es wird bald fallen gelassen .

288
desseim

Mit Kotlin 1.0.0+ funktioniert Folgendes:

@Rule @JvmField 
val mActivityRule = ActivityTestRule(MainActivity::class.Java)
236
jkschneider

Benutze das:

@get:Rule
var mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(MainActivity::class.Java)
11

Mit Kotlin 1.0.4:

val mActivityRule: ...
    @Rule get
11
janin