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

Lesezeit: 6 Minuten

Benutzer-Avatar
Geob-o-matic

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 :/

  • Derzeit unterstützt Kotlin nicht die Veröffentlichung von Feldern, die unterstützende Eigenschaften sind, aber wir arbeiten daran

    – Andrej Breslav

    29. April 2015 um 14:20 Uhr

  • Gibt es dazu ein Bugtracking?

    – Geob-o-matic

    29. April 2015 um 14:29 Uhr

  • youtrack.jetbrains.com/issue/KT-3441

    – Andrej Breslav

    1. Mai 2015 um 15:13 Uhr

Benutzer-Avatar
dessei

JUnit ermöglicht die Bereitstellung von Regeln über ein Testklassenfeld oder eine Getter-Methode.

Was Sie kommentiert haben, ist in Kotlin a Eigentum die JUnit jedoch nicht erkennt.

Hier sind die Möglichkeiten, eine JUnit-Regel in Kotlin anzugeben:

Durch eine annotierte Getter-Methode

Von M13der Anmerkungsprozessor unterstützt Anmerkungsziele. Wenn du schreibst

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

Die Anmerkung verwendet jedoch die property target standardmäßig (für Java nicht sichtbar).

Sie können jedoch den Eigenschafts-Getter annotieren, 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 erreichen Sie dasselbe Ergebnis wie mit @get:Rule).

Durch ein kommentiertes öffentliches Feld

Kotlin erlaubt auch seit dem Beta-Kandidaten um Eigenschaften deterministisch in Felder auf der JVM zu kompilieren, in diesem Fall gelten die Anmerkungen und Modifikatoren für das generierte Feld. Dies geschieht mit Kotlins @JvmField Eigenschaftsanmerkung wie von @jkschneider beantwortet.


Randnotiz: Stellen Sie sicher, dass Sie das voranstellen Rule Anmerkung mit einem @ Charakter wie er jetzt ist die einzige unterstützte Syntax für Anmerkungenund vermeiden @publicField als es wird bald fallen gelassen.

  • Macht es? Ich bekomme immer noch den Fehler und es ist öffentlich mit M14 (0.14.449)

    – Geob-o-matic

    10. Oktober 2015 um 14:48 Uhr

  • scheint @publicField zu brauchen, aber es ist veraltet, also habe ich lateinit wie von IDE vorgeschlagen ausprobiert, aber dann bellt es mich an und sagt, dass lateinit nur auf änderbar angewendet werden kann (der Artikel des Blogs sagt etwas anderes …)

    – Geob-o-matic

    10. Oktober 2015 um 14:54 Uhr

  • Aktualisierte meine Antwort;) Wie für lateinit vales wurde in M14 entfernt, da es die Unveränderlichkeit des Feldes nicht vollständig durchgesetzt hat, siehe die [M14 release blog post](blog.jetbrains.com/kotlin/2015/10/kotlin-m14-is-out/).

    – dessei

    10. Oktober 2015 um 15:29 Uhr

  • Was ist @get: Anmerkung? Es funktioniert auch nicht in meiner Situation.

    – Aleksandrbel

    20. September 2018 um 6:23 Uhr

  • Nach dem Ändern von Rule in @get: Rule wurde es behoben. Vielen Dank

    – der Mädchencode

    21. März um 10:49 Uhr

Benutzer-Avatar
Jonathan Schneider

Mit Kotlin 1.0.0+ funktioniert das:

@Rule @JvmField 
val mActivityRule = ActivityTestRule(MainActivity::class.java)

  • Und es löste das Problem des Flusenwerkzeugs, das sich darüber beschwerte, dass die Öffentlichkeit ein Qualifizierer für die Regel war, war überflüssig.

    – Rauben

    27. März 2016 um 23:31 Uhr

  • Ja \@JvmField ist entscheidend oder verwenden Sie lieber \@get:Rule

    – Michal Ziobro

    14. Januar 2019 um 10:58 Uhr

  • Funktioniert nur auf Endfeldern. Funktioniert nicht für eine Regel wie var wireMockRule = WireMockRule(wireMockConfig().dynamicPort()).

    – Abhijit Sarkar

    14. März 2019 um 6:33 Uhr

Benutze das:

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

  • Möchtest du eine Erklärung hinzufügen?

    – Peter Chaula

    19. April 2019 um 20:45 Uhr

Anstatt von @Rule du solltest benutzen @get:Rule.

Mit Kotlin 1.0.4:

val mActivityRule: ...
    @Rule get

  • Damit ist die Frage nicht beantwortet. Sobald Sie über einen ausreichenden Ruf verfügen, können Sie jeden Beitrag kommentieren. stattdessen, Geben Sie Antworten, die keine Klärung durch den Fragesteller erfordern. – Aus Bewertung

    – Jignesh Ansodariya

    10. Oktober 2016 um 5:38 Uhr

  • @JigneshAnsodariya – Ich habe eine Überprüfung durchgeführt und diese Antwort liefert eine Antwort auf das, was gefragt wurde. Weitere Informationen dazu, wie dies funktioniert, finden Sie unter folgendem Link – kotlinlang.org/docs/reference/…

    – Praveer Gupta

    4. November 2016 um 17:46 Uhr


  • Bei diesem Ansatz gibt es ein Problem. Wenn Sie auf die zu testende Aktivität zugreifen möchten (z. B.: assertTrue(activityRule.activity.isFinishing)), wird der Eigenschafts-Getter aufgerufen, wodurch eine neue Regel erstellt wird. In diesem Fall ist activityRule.activity null.

    – makowkastar

    30. Oktober 2017 um 8:20 Uhr

  • Damit ist die Frage nicht beantwortet. Sobald Sie über einen ausreichenden Ruf verfügen, können Sie jeden Beitrag kommentieren. stattdessen, Geben Sie Antworten, die keine Klärung durch den Fragesteller erfordern. – Aus Bewertung

    – Jignesh Ansodariya

    10. Oktober 2016 um 5:38 Uhr

  • @JigneshAnsodariya – Ich habe eine Überprüfung durchgeführt und diese Antwort liefert eine Antwort auf das, was gefragt wurde. Weitere Informationen dazu, wie dies funktioniert, finden Sie unter folgendem Link – kotlinlang.org/docs/reference/…

    – Praveer Gupta

    4. November 2016 um 17:46 Uhr


  • Bei diesem Ansatz gibt es ein Problem. Wenn Sie auf die zu testende Aktivität zugreifen möchten (z. B.: assertTrue(activityRule.activity.isFinishing)), wird der Eigenschafts-Getter aufgerufen, wodurch eine neue Regel erstellt wird. In diesem Fall ist activityRule.activity null.

    – makowkastar

    30. Oktober 2017 um 8:20 Uhr

1351190cookie-checkKotlin und neue ActivityTestRule : Die @Rule muss öffentlich sein

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy