android - Kotlin y la nueva ActivityTestRule: la @Rule debe ser pública
testing android-espresso (4)
Con Kotlin 1.0.0+, esto funciona:
@Rule @JvmField
val mActivityRule = ActivityTestRule(MainActivity::class.java)
Estoy tratando de hacer una prueba de IU para mi aplicación de Android en Kotlin. Desde el nuevo sistema que usa ActivityTestRule, no puedo hacer que funcione: se compila correctamente, y en tiempo de ejecución, obtengo:
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)
Así es como declaró mActivityRule:
RunWith(javaClass<AndroidJUnit4>())
LargeTest
public class RadisTest {
Rule
public val mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(javaClass<MainActivity>())
...
}
Ya es público: /
Con Kotlin 1.0.4:
val mActivityRule: ...
@Rule get
JUnit permite proporcionar reglas a través de un campo de clase de prueba o un método getter.
Sin embargo, lo que anotó es en Kotlin una propiedad , que JUnit no reconocerá.
Estas son las formas posibles de especificar una regla JUnit en Kotlin:
A través de un método getter anotado
Desde M13 , el procesador de anotación admite objetivos de anotación . Cuando escribes
@Rule
public val mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(javaClass<MainActivity>())
sin embargo, la anotación utilizará el destino de la
property
de forma predeterminada (no visible para Java).
Sin embargo, puede anotar el captador de propiedades, que también es público y, por lo tanto, cumple los requisitos de JUnit para un captador de reglas:
@get:Rule
public val mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(javaClass<MainActivity>())
Alternativamente, puede definir la regla con una función en lugar de una propiedad (logrando manualmente el mismo resultado que con
@get:Rule
).
A través de un campo público anotado
Kotlin también permite,
ya que el candidato beta,
compilar de manera determinista las propiedades de los campos en la JVM, en cuyo caso las anotaciones y los modificadores se aplican al campo generado.
Esto se realiza utilizando la anotación de propiedad
@JvmField
de Kotlin, según lo
respondió @jkschneider
.
Nota al margen: asegúrese de prefijar la anotación de
Rule
con un carácter
@
, ya que ahora es
la única sintaxis compatible para las anotaciones
, y evite
@publicField
ya que
pronto se eliminará
.
Utilizar esta:
@get:Rule
var mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(MainActivity::class.java)