Kotlin和new ActivityTestRule: @Rule必须是公共的

我试图在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>())


...
}

它已经是公共的:/

48585 次浏览

使用Kotlin 1.0.0+,这是有效的:

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

JUnit允许通过测试类字段或getter方法提供规则。

你注释的东西在Kotlin中是财产, JUnit不会识别。

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

通过一个带注释的getter方法

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

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

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

然而,你可以注释属性getter,它也是公共的,因此满足JUnit对规则getter的要求:

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

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

通过一个带注释的公共字段

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


附注:一定要用@字符作为Rule注释的前缀,因为它现在是唯一支持的注释语法,并避免@publicField,因为它是很快就会被抛弃

在Kotlin 1.0.4中:

val mActivityRule: ...
@Rule get

用这个:

@get:Rule
var mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(MainActivity::class.java)

你应该使用@get:Rule而不是@Rule