Kotlin และ ActivityTestRule ใหม่: @Rule ต้องเป็นสาธารณะ


264

ฉันพยายามทำการทดสอบ UI สำหรับแอพ Android ของฉันใน Kotlin เนื่องจากระบบใหม่ที่ใช้ 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 อนุญาตให้จัดทำกฎผ่านเขตข้อมูลทดสอบหรือเมธอด getter

สิ่งที่คุณทำหมายเหตุประกอบอยู่ใน Kotlin ซึ่งเป็นคุณสมบัติที่ JUnit ไม่รู้จัก

นี่เป็นวิธีที่เป็นไปได้ในการระบุกฎ JUnit ใน Kotlin:

ผ่านวิธี 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 ยังอนุญาตให้ผู้สมัครรุ่นเบต้าสามารถรวบรวมคุณสมบัติไปยังเขตข้อมูลใน JVM ในกรณีนี้คำอธิบายประกอบและตัวดัดแปลงจะใช้กับเขตข้อมูลที่สร้างขึ้น นี้จะกระทำโดย Kotlin ของ@JvmFieldสถานที่ให้บริการคำอธิบายประกอบเป็นคำตอบโดย @jkschneider


หมายเหตุด้านข้าง: ให้แน่ใจว่าได้ใส่คำนำหน้าRuleคำอธิบายประกอบด้วย@ตัวอักษรเนื่องจากขณะนี้เป็นไวยากรณ์ที่ได้รับการสนับสนุนสำหรับคำอธิบายประกอบเท่านั้นและหลีกเลี่ยง@publicFieldเนื่องจากจะถูกลบ


ทำมัน? ฉันยังคงได้รับข้อผิดพลาดและเป็นสาธารณะกับ M14 (0.14.449)
Geob-o-matic

ดูเหมือนว่าจะต้อง @publicField แต่มันเลิกใช้แล้วดังนั้นฉันจึงลองใช้ช้าที่แนะนำโดย IDE แต่จากนั้นมันก็เห่าใส่ฉันว่า Lateinit สามารถใช้ได้เฉพาะกับที่ไม่แน่นอน (บทความของบล็อกบอกว่าเป็นอย่างอื่น ... )
Geob-o-matic

1
อัปเดตคำตอบของฉัน;) ส่วนlateinit valนั้นจะถูกลบใน M14 เนื่องจากไม่ได้บังคับใช้ฟิลด์อย่างเต็มที่ให้ดูที่ [M14 release blog post post] (blog.jetbrains.com/kotlin/2015/10/kotlin- M14-คือออก /)
desseim

@get คืออะไร: คำอธิบายประกอบ? มันไม่ทำงานในสถานการณ์ของฉัน
aleksandrbel

252

ด้วย Kotlin 1.0.0+ การทำงานนี้:

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

1
และมันก็แก้ปัญหาของเครื่องมือผ้าสำลีที่บ่นว่าประชาชนมีคุณสมบัติในกฎนั้นซ้ำซ้อน
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 Gupta

มีปัญหากับวิธีนี้ หากคุณต้องการเข้าถึงกิจกรรมภายใต้การทดสอบ (ตัวอย่างเช่น: assertTrue (activityRule.activity.isFinishing)) คุณสมบัติ getter จะถูกเรียกใช้ดังนั้นจึงสร้างกฎใหม่ ในกรณีนี้ activityRule.activity จะเป็นโมฆะ
makovkastar

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.