J'essaie de faire tester l'interface utilisateur de mon application Android dans Kotlin. Depuis le nouveau système utilisant ActivityTestRule, je ne peux pas le faire fonctionner: il se compile correctement, et à l'exécution, j'obtiens:
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)
Voici comment j'ai déclaré mActivityRule:
RunWith(javaClass<AndroidJUnit4>())
LargeTest
public class RadisTest {
Rule
public val mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(javaClass<MainActivity>())
...
}
C'est déjà public: /
JUnit permet de fournir des règles via un champ de classe de test ou une méthode getter.
Ce que vous avez annoté est dans Kotlin une propriété que JUnit ne reconnaît pas.
Voici les manières possibles de spécifier une règle JUnit dans Kotlin:
à partir de M1 , le processeur d'annotation prend en charge les cibles d'annotation . Quand tu écris
_@Rule
public val mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(javaClass<MainActivity>())
_
cependant, l'annotation utilisera la cible property
par défaut (non visible pour Java).
Vous pouvez toutefois annoter le getter de la propriété, qui est également public et satisfait donc aux exigences de JUnit pour un getter de règles:
_@get:Rule
public val mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(javaClass<MainActivity>())
_
Vous pouvez également définir la règle avec une fonction au lieu d'une propriété (obtenir manuellement le même résultat qu'avec _@get:Rule
_).
Kotlin permet également à depuis le candidat bêta de compiler de manière déterministe les propriétés des champs de la machine virtuelle, auquel cas les annotations et les modificateurs s’appliquent au champ généré. Ceci est fait en utilisant l'annotation de la propriété @JvmField
de Kotlin en tant que répond par @jkschneider .
Note latérale: assurez-vous de préfixer l'annotation Rule
avec un caractère _@
_ tel qu'il est maintenant la seule syntaxe prise en charge pour les annotations , et évitez _@publicField
_ - sera bientôt abandonné .
Avec Kotlin 1.0.0+, cela fonctionne:
@Rule @JvmField
val mActivityRule = ActivityTestRule(MainActivity::class.Java)
Utilisez ceci:
@get:Rule
var mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(MainActivity::class.Java)
Avec Kotlin 1.0.4:
val mActivityRule: ...
@Rule get