Я пытаюсь сделать тест интерфейса для моего приложения для Android в Kotlin. Поскольку новая система использует 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>())
...
}
Это уже публично: /
android
testing
android-espresso
kotlin
Geob-O-Matic
источник
источник
Ответы:
JUnit позволяет предоставлять правила через поле тестового класса или метод получения.
Тем не менее, в Kotlin вы аннотировали свойство , которое JUnit не распознает.
Вот возможные способы указать правило JUnit в Kotlin:
С помощью аннотированного метода получения
Начиная с M13 , процессор аннотаций поддерживает цели аннотаций . Когда ты пишешь
тем не менее, аннотация будет использовать
property
цель по умолчанию (не видимый для Java).Однако вы можете аннотировать свойство get, которое также является общедоступным и, таким образом, удовлетворяет требованиям JUnit для правила get:
В качестве альтернативы вы можете определить правило с помощью функции вместо свойства (получая вручную тот же результат, что и с
@get:Rule
).Через аннотированное публичное поле
Kotlin также позволяет, поскольку бета-кандидат детерминистически компилирует свойства полей в JVM, и в этом случае аннотации и модификаторы применяются к сгенерированному полю. Это делается с помощью
@JvmField
аннотации свойств Kotlin, на которую отвечает @jkschneider .Примечание: обязательно добавьте
Rule
аннотацию к@
символу, так как теперь это единственный поддерживаемый синтаксис для аннотаций , и избегайте,@publicField
поскольку он скоро будет удален .источник
lateinit val
, он был удален в M14, так как он не полностью обеспечивал неизменность поля, см. [Сообщение в блоге о выпуске M14] (blog.jetbrains.com/kotlin/2015/10/kotlin- M14-это выход /).С Kotlin 1.0.0+ это работает:
источник
var wireMockRule = WireMockRule(wireMockConfig().dynamicPort())
.Использовать это:
источник
С Kotlin 1.0.4:
источник
Вместо этого
@Rule
вы должны использовать@get:Rule
.источник