कोटलिन और नई एक्टिविटीटेस्ट नियम: @ नियम सार्वजनिक होना चाहिए


264

मैं कोटलिन में अपने एंड्रॉइड ऐप के लिए यूआई परीक्षण बनाने की कोशिश कर रहा हूं। जब से नया सिस्टम ActivTestRule का उपयोग कर रहा है, मैं इसे काम नहीं कर सकता: यह सही ढंग से संकलित करता है, और रनटाइम पर, मुझे मिलता है:

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
वर्तमान में, कोटलिन उन क्षेत्रों को बनाने का समर्थन नहीं करता है जो गुणों को सार्वजनिक कर रहे हैं, लेकिन हम इस पर काम कर रहे हैं
एंड्री ब्रेस्लाव

क्या कोई बग इसे ट्रैक कर रहा है?
Geob-o-matic

जवाबों:


316

JUnit एक टेस्ट क्लास फील्ड या एक गेट्टर विधि के माध्यम से नियम प्रदान करने की अनुमति देता है।

आपने जो एनोटेट किया है वह कोटलिन में एक संपत्ति है, हालांकि, जो जुनीत को मान्यता नहीं देगा।

Kotlin में एक JUnit नियम निर्दिष्ट करने के संभावित तरीके इस प्रकार हैं:

एक एनोटेट गेट्टर विधि के माध्यम से

M13 से , एनोटेशन प्रोसेसर एनोटेशन लक्ष्यों का समर्थन करता है । जब आप लिखते हैं

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

हालांकि, एनोटेशन propertyडिफ़ॉल्ट रूप से लक्ष्य का उपयोग करेगा (जावा के लिए दृश्यमान नहीं)।

हालांकि आप संपत्ति पाने वाले को एनोटेट कर सकते हैं, जो सार्वजनिक भी है और इस तरह एक नियम पाने वाले के लिए JUnit आवश्यकताओं को संतुष्ट करता है:

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

वैकल्पिक रूप से, आप एक संपत्ति के बजाय एक फ़ंक्शन के साथ नियम को परिभाषित कर सकते हैं (मैन्युअल रूप से उसी परिणाम को प्राप्त कर सकते हैं @get:Rule)।

एक एनोटेट सार्वजनिक क्षेत्र के माध्यम से

कोटलिन बीटा उम्मीदवार को जेवीएम पर फ़ील्ड के लिए गुणात्मक रूप से संकलित करने के लिए अनुमति देता है , इस मामले में एनोटेशन और संशोधक उत्पन्न फ़ील्ड पर लागू होते हैं। यह @jkschneider द्वारा उत्तर के@JvmField रूप में कोटलिन की संपत्ति एनोटेशन का उपयोग करके किया जाता है ।


साइड नोट: Ruleकिसी @वर्ण के साथ एनोटेशन को उपसर्ग करना सुनिश्चित करें क्योंकि यह अब एनोटेशन के लिए एकमात्र समर्थित सिंटैक्स है , और इससे बचें @publicFieldक्योंकि यह जल्द ही हटा दिया जाएगा


क्या यह? मुझे अभी भी त्रुटि मिलती है और यह M14 (0.14.449) के साथ सार्वजनिक है
जियोब-ओ-मैटिक

लगता है @publicField की जरूरत है, लेकिन यह पदावनत है, इसलिए मैंने IDE द्वारा सुझाए गए अनुसार लेटनीट की कोशिश की, लेकिन फिर मुझ पर यह कहते हुए भौंकने लगा कि लेटइनिट केवल म्यूटेबल पर लागू किया जा सकता है (ब्लॉग का लेख अन्यथा ...)
जियोब-ओ-मैटिक

1
मेरे उत्तर को अपडेट करें;) जैसा कि lateinit valयह एम 14 में हटा दिया गया है क्योंकि यह पूरी तरह से क्षेत्र की अपरिहार्यता को लागू नहीं करता है, [एम 14 रिलीज ब्लॉग पोस्ट] (blog.jetbrains.com/kotlin/2015/10/kotlin- देखें M14-है-बाहर /)।
डेसिम

@Get: एनोटेशन क्या है? यह मेरी स्थिति में भी काम नहीं करता है।
aleksandrbel

252

कोटलिन 1.0.0+ के साथ, यह काम करता है:

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

1
और इसने लिंट टूल की समस्या को हल कर दिया, जिसमें शिकायत थी कि जनता नियम के अनुसार योग्य थी।
रोब

Yes \ @JvmField महत्वपूर्ण है या इसके बजाय \ @get का उपयोग करें: नियम
माइकल जाइब्रो

केवल अंतिम क्षेत्रों पर काम करता है। जैसे नियम के लिए काम नहीं करेंगे var wireMockRule = WireMockRule(wireMockConfig().dynamicPort())
अभिजीत सरकार


12

कोटलिन 1.0.4 के साथ:

val mActivityRule: ...
    @Rule get

यह प्रश्न का उत्तर प्रदान नहीं करता है। एक बार आपके पास पर्याप्त प्रतिष्ठा होने के बाद आप किसी भी पोस्ट पर टिप्पणी कर पाएंगे ; इसके बजाय, ऐसे उत्तर प्रदान करें जिन्हें पूछने वाले से स्पष्टीकरण की आवश्यकता न हो । - रिव्यू से
जिग्नेश अंसोदरी

10
@ जिग्नेशअनसोदरिया - मैंने एक चेक किया और यह जवाब जो पूछा गया है उसका उत्तर प्रदान करता है। यह कैसे काम कर रहा है इसके बारे में अधिक जानकारी निम्नलिखित लिंक पर मिल सकती है - kotlinlang.org/docs/reference/…
प्रवीर गुप्ता

इस दृष्टिकोण के साथ एक समस्या है। यदि आप परीक्षण के तहत गतिविधि का उपयोग करना चाहते हैं (उदाहरण के लिए: assertTrue (activityRule.activity.isFinishing)), संपत्ति पाने वाले को बुलाया जाएगा, इस प्रकार एक नया नियम बनाया जाएगा। इस स्थिति में activityRule.activity शून्य हो जाएगी।
makovkastar

0

इसके बजाय @Rule, आपको उपयोग करना चाहिए @get:Rule

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.