Kotlin和新的ActivityTestRule:@规则必须公开

我正在尝试在Kotlin中为我的Android应用程序进行UI测试。 由于使用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不会承认。

以下是在Kotlin中指定JUnit规则的可能方法:

通过注释的getter方法

从M13开始 ,注释处理器支持注释目标 。 当你写

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

虽然,注释将默认使用property目标(对Java不可见)。

您可以注释属性getter,但也是公共的,因此满足规则getter的JUnit要求:

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

或者,您可以使用函数而不是属性来定义规则(手动实现与@get:Rule相同的结果)。

通过注释的公共领域

Kotlin还允许beta候选者确定性地将属性编译到JVM上的字段,在这种情况下,注释和修饰符适用于生成的字段。 这是通过@jkschneider回答使用Kotlin的@JvmField属性注释完成的 。


注意:一定要在Rule注释前添加一个@字符,因为它现在是注释唯一支持的语法 ,并且避免@publicField因为它很快会被删除 。

使用Kotlin 1.0.0+,这个工作:

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

用Kotlin 1.0.4:

 val mActivityRule: ... @Rule get