Saya mencoba membuat tes UI untuk aplikasi Android saya di Kotlin. Karena sistem baru menggunakan ActivityTestRule, saya tidak bisa membuatnya bekerja: ia mengkompilasi dengan benar, dan saat runtime, saya mendapatkan:
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)
Inilah cara saya mendeklarasikan mActivityRule:
RunWith(javaClass<AndroidJUnit4>())
LargeTest
public class RadisTest {
Rule
public val mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(javaClass<MainActivity>())
...
}
Sudah publik: /
android
testing
android-espresso
kotlin
Geob-o-matic
sumber
sumber
Jawaban:
JUnit memungkinkan penyediaan aturan melalui bidang kelas uji atau metode pengambil.
Apa yang Anda anotasi di Kotlin adalah properti , yang JUnit tidak akan kenal.
Berikut adalah cara yang mungkin untuk menentukan aturan JUnit di Kotlin:
Melalui metode pengambil beranotasi
Dari M13 , prosesor anotasi mendukung target anotasi . Ketika Anda menulis
meskipun, anotasi akan menggunakan
property
target secara default (tidak terlihat oleh Java).Anda dapat membuat anotasi pengambil properti, yang juga publik dan dengan demikian memenuhi persyaratan JUnit untuk pengambil aturan:
Atau, Anda bisa mendefinisikan aturan dengan fungsi alih-alih properti (mencapai hasil yang sama dengan secara manual
@get:Rule
).Melalui bidang publik beranotasi
Kotlin juga memungkinkan karena kandidat beta untuk secara kompilasi mengkompilasi properti ke bidang pada JVM, dalam hal ini anotasi dan pengubah berlaku untuk bidang yang dihasilkan. Ini dilakukan dengan menggunakan
@JvmField
anotasi properti Kotlin seperti dijawab oleh @jkschneider .Catatan sisi: pastikan untuk mengawali
Rule
anotasi dengan@
karakter karena sekarang hanya sintaks yang didukung untuk anotasi , dan hindari@publicField
karena akan segera dihapus .sumber
lateinit val
, telah dihapus di M14 karena tidak sepenuhnya menegakkan keabadian lapangan, lihat [posting blog rilis M14] (blog.jetbrains.com/kotlin/2015/10/10/kotlin- m14-is-out /).Dengan Kotlin 1.0.0+, ini berfungsi:
sumber
var wireMockRule = WireMockRule(wireMockConfig().dynamicPort())
.Gunakan ini:
sumber
Dengan Kotlin 1.0.4:
sumber
Alih-alih
@Rule
, Anda harus menggunakan@get:Rule
.sumber