Kotlinと新しいActivityTestRule:@Ruleは公開する必要があります


264

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>())

   ...
}

すでに公開されています:/


3
現在、Kotlinはバッキングプロパティであるフィールドのパブリック化をサポートしていませんが、現在取り組んでいます
Andrey Breslav

これを追跡するバグはありますか?
Geob-o-matic

回答:


316

JUnitでは、テストクラスフィールドまたはゲッターメソッドを通じてルールを提供できます。

あなたが注釈を付けたのはKotlinのプロパティですが、JUnitはそれを認識しません。

KotlinでJUnitルールを指定する方法は次のとおりです。

アノテーション付きゲッターメソッドを使用

M13以降、注釈プロセッサは注釈ターゲットをサポートします。あなたが書くとき

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

ただし、アノテーションはpropertyデフォルトでターゲットを使用します(Javaからは見えません)。

ただし、プロパティゲッターに注釈を付けることもできます。これもパブリックであり、ルールゲッターのJUnit要件を満たします。

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

または、プロパティの代わりに関数を使用してルールを定義することもできます(と同じ結果を手動で取得します@get:Rule)。

注釈付きのパブリックフィールドを介して

Kotlinでは、ベータ版の候補者が決定的にプロパティをJVMのフィールドにコンパイルすることもできます。その場合、注釈と修飾子は生成されたフィールドに適用されます。これは、@jkschneiderによって回答された Kotlinの@JvmFieldプロパティアノテーションを使用して行われます


補足:Rule注釈の前に必ず@文字を付けてください。これは、注釈サポートされている唯一の構文であるためです。すぐに削除さ@publicFieldれるので避けてください。


そうですか?それでもエラーが発生し、M14(0.14.449)で公開されます
Geob-o-matic

@publicFieldが必要と思われますが、非推奨であるため、IDEの提案に従ってlateinitを試しましたが、lateinitはミュータブルにのみ適用できると私に怒鳴りました(ブログの記事には別の方法が記載されています…)
Geob-o-matic

1
私の回答を更新しました;)についてlateinit valは、フィールドの不変性を完全に強制しなかったため、M14で削除されました。[M14リリースのブログ投稿](blog.jetbrains.com/kotlin/2015/10/kotlin- m14-is-out /)。
2015年

@get:アノテーションとは何ですか?また、私の状況では機能しません。
aleksandrbel 2018

252

Kotlin 1.0.0+では、これは機能します。

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

1
そしてそれは、公衆がルールの修飾子であると不平を言うlintツールの問題は冗長でした。
Rob

はい\ @JvmFieldが重要かを使用することであるという\ @get:ルール
のMichałZiobro

最終フィールドでのみ機能します。のようなルールでは機能しませんvar wireMockRule = WireMockRule(wireMockConfig().dynamicPort())
Abhijit Sarkar


12

Kotlin 1.0.4の場合:

val mActivityRule: ...
    @Rule get

これは質問に対する答えを提供しません。十分な評判られると、どの投稿にもコメントできるようになります。代わりに、質問者からの説明を必要としない回答を提供してください。- 口コミより
Jignesh Ansodariya

10
@JigneshAnsodariya-私はチェックをしました、そしてこの答えは尋ねられたものへの答えを提供します。-これが動作している方法についての詳しい情報は、以下のリンクで見ることができkotlinlang.org/docs/reference/...
Praveerグプタ

このアプローチには問題があります。テスト中のアクティビティにアクセスする場合(例:assertTrue(activityRule.activity.isFinishing))、プロパティゲッターが呼び出され、新しいルールが作成されます。この場合、activityRule.activityはnullになります。
makovkastar 2017年

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.