Kotlin ve yeni ActivityTestRule: @Rule herkese açık olmalı


264

Kotlin'deki android uygulamam için UI testi yapmaya çalışıyorum. ActivityTestRule kullanan yeni sistem beri, çalışmasını sağlayamıyorum: doğru derler ve çalışma zamanında, ben olsun:

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)

İşte nasıl mActivityRule ilan:

RunWith(javaClass<AndroidJUnit4>())
LargeTest
public class RadisTest {

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

   ...
}

Zaten herkese açık: /


3
Şu anda Kotlin, mülkleri halka açık alanların yapımını desteklemiyor, ancak üzerinde çalışıyoruz
Andrey Breslav

Bunu izleyen bir hata var mı?
Geob-o-matic

Yanıtlar:


316

JUnit, bir test sınıfı alanı veya alıcı yöntemi aracılığıyla kuralların sağlanmasına izin verir.

Ek açıkladığınız şey Kotlin'de JUnit'in tanımayacağı bir özelliktir .

Kotlin'de bir JUnit kuralı belirtmenin olası yolları şunlardır:

Ek açıklamalı alıcı yöntemi ile

M13 itibaren , ek açıklama işlemci açıklama hedeflerini destekler . Yazdığın zaman

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

ancak ek açıklama propertyhedefi varsayılan olarak kullanır (Java tarafından görülemez).

Ancak, aynı zamanda herkese açık olan ve böylece kural alıcısı için JUnit gereksinimlerini karşılayan mülk alıcısına açıklama ekleyebilirsiniz:

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

Alternatif olarak, kuralı bir özellik yerine bir işlevle tanımlayabilirsiniz (ile aynı sonucu manuel olarak elde etme @get:Rule).

Açıklamalı bir ortak alanda

Kotlin ayrıca beta adayının JVM'deki alanlara belirleyici bir şekilde özellikler derlemesine izin verir , bu durumda ek açıklamalar ve değiştiriciler oluşturulan alana uygulanır. Bu, @jkschneider tarafından cevaplandığı şekliyle Kotlin'in@JvmField özellik açıklaması kullanılarak yapılır .


Yan Not: kullandığınızdan emin olun Rulebir ile ek açıklama @şimdi olduğu gibi karakteri yalnızca desteklenen ek açıklamalar için sözdizimi ve önlemek @publicFieldo kadar kısa sürede atılır .


Yapar? Hala hatayı alıyorum ve M14 (0.14.449) ile herkese açık
Geob-o-matic

@publicField'e ihtiyacı var gibi görünüyor, ancak kullanımdan kaldırıldı, bu yüzden IDE tarafından önerildiği gibi lateinit'i denedim, ancak sonra lateinit'in sadece mutable üzerine uygulanabileceğini söyler (blogun makalesi aksini söylüyor…)
Geob-o-matic

1
Cevabım güncellendi;) lateinit valAlanın değişmezliğini tam olarak uygulamadığı için M14'te kaldırıldı, bkz. [M14 sürüm blog yayını] (blog.jetbrains.com/kotlin/2015/10/kotlin- m14-is-çıkış /).
desseim

@Get: ek açıklama nedir? Benim durumumda da çalışmıyor.
aleksandrbel

252

Kotlin 1.0.0+ ile bu işe yarar:

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

1
Ve tiftik aracının sorununu çözdü, halkın kural üzerinde niteleyici olduğundan şikayet ediyordu.
Rob

Evet \ @JvmField çok önemli veya oldukça kullan \ @get: Kural
Michał Ziobro

Sadece son alanlarda çalışır. Gibi bir kural için çalışmaz var wireMockRule = WireMockRule(wireMockConfig().dynamicPort()).
Abhijit Sarkar


12

Kotlin 1.0.4 ile:

val mActivityRule: ...
    @Rule get

Bu soruya bir cevap sağlamaz. Yeterli bir üne sahip olduğunuzda , herhangi bir yazı hakkında yorum yapabilirsiniz ; bunun yerine askerden açıklama gerektirmeyen cevaplar verin . - Yorumdan
Jignesh Ansodariya

10
@JigneshAnsodariya - Bir kontrol yaptım ve bu cevap ne sorulduğuna bir cevap veriyor. Bunun nasıl çalıştığı hakkında daha fazla bilgi aşağıdaki bağlantıda bulunabilir - kotlinlang.org/docs/reference/…
Praveer Gupta

Bu yaklaşımla ilgili bir sorun var. Test edilen etkinliğe erişmek istiyorsanız (örneğin: assertTrue (activityRule.activity.isFinishing)), özellik alıcısı çağrılır ve böylece yeni bir kural oluşturulur. Bu durumda activityRule.activity boş olacaktır.
makovkastar

0

Bunun yerine @Rulekullanmalısınız @get:Rule.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.