Kotlin и новый ActivityTestRule: @Rule должен быть общедоступным

Я пытаюсь сделать UI-тест для моего приложения Android в Котлине. Поскольку новая система использует ActivityTestRule, я не могу заставить ее работать: она компилируется правильно, и во время выполнения я получаю:

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) 

Вот как я объявил mActivityRule:

 RunWith(javaClass<AndroidJUnit4>()) LargeTest public class RadisTest { Rule public val mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(javaClass<MainActivity>()) ... } 

Он уже опубликован: /

JUnit позволяет предоставлять правила через поле тестового класса или метод getter.

То, что вы отметили в Kotlin, является собственностью , которую JUnit не узнает.

Вот возможные способы указать правило JUnit в Котлине:

Через аннотированный метод геттера

Из M13 процессор аннотаций поддерживает цели аннотации . Когда вы пишете

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

Тем не менее, аннотация будет использовать целевой объект по умолчанию (не отображается в Java).

Однако вы можете аннотировать свойство getter, которое также является общедоступным и, таким образом, удовлетворяет требованиям JUnit для правила getter:

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

В качестве альтернативы вы можете определить правило с помощью функции вместо свойства (достижение вручную того же результата, что и с помощью @get:Rule ).

Через аннотированное публичное поле

Kotlin также позволяет, так как бета-кандидат детерминистически компилирует свойства в поля на JVM, и в этом случае аннотации и модификаторы применяются к сгенерированному полю. Это делается с помощью аннотации свойств Kotlin @JvmField как было указано @jkschneider .


Боковое примечание: обязательно Rule аннотацию Rule символом @ как теперь это единственный поддерживаемый синтаксис аннотаций и избегать @publicField поскольку он скоро будет @publicField .

С Kotlin 1.0.0+ это работает:

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

С Kotlin 1.0.4:

 val mActivityRule: ... @Rule get