2010-07-28 10 views
15

कई आवेदन में मैं अक्सर एल्गोरिदम, जो समर्पित उप एल्गोरिदम (या कोड का बस अच्छी तरह से परिभाषित टुकड़े) का इस्तेमाल करते हैं की है।मैं जावा में स्थानीय आंतरिक वर्ग विधियों का परीक्षण कैसे करूं?

public class OldStyle { 

    public int mainAlg() { 
     int x = subAlg01(); 
     int y = subAlg02(); 
     int z = x * y; 
     return z; 
    } 

    private int subAlg01() { 
     return 3; 
    } 

    private int subAlg02() { 
     return 5; 
    } 
} 

यह ठीक काम किया, लेकिन मैं कर रहा पसंद नहीं आया:

अब तक, जब मैं मुख्य एल्गोरिथ्म लिखा था, मैं प्रत्येक उप एल्गोरिथ्म के लिए एक निजी विधि उदाहरण नीचे (ओल्डस्टएल) में की तरह बनाया तरीकों का प्रसार (subAlg01 और subAlg02) जो, भले ही निजी, केवल एक विधि (mainAlg) द्वारा उपयोग किया जाता था।

हाल ही में मैं स्थानीय इनर क्लासों उपयोग dicovered और अब मेरा उदाहरण (NEWSTYLE) है:

public class NewStyle { 

    public int mainAlg() { 
     class Nested { 

      public int subAlg01() { 
       return 3; 
      } 

      public int subAlg02() { 
       return 5; 
      } 
     } 
     Nested n = new Nested(); 
     int x = n.subAlg01(); 
     int y = n.subAlg02(); 
     int z = x * y; 
     return z; 
    } 
} 

मैं इसे बहुत पसंद है लेकिन अब मैं निम्नलिखित समस्या है: मैं subAlg01 और subAlg02 का उपयोग कर कैसे परीक्षण करते हैं JUnit?

वैसे: मैं ग्रहण का उपयोग कर रहा हूँ।

आपकी मदद के लिए धन्यवाद।

संपादित करें: मैं बेहतर व्याख्या करने की कोशिश करता हूं: मैंने कहा है, एक सॉर्टिंग एल्गोरिदम है और मैं यह सुनिश्चित करने के लिए परीक्षण करना चाहता हूं कि यह अपेक्षित रूप से चलता है। इस सॉर्टिंग एल्गोरिदम का उपयोग क्लास एक्स के केवल विधि एम द्वारा किया जाता है। मैं इसे क्लास एक्स का एक निजी तरीका बना सकता हूं लेकिन क्लास एक्स में आमतौर पर सॉर्टिंग के साथ कुछ भी नहीं है, तो सॉर्टिंग विधि के साथ कक्षा एक्स को "खराब" क्यों करें? तो मैंने इसे विधि एम के अंदर रखा। कुछ समय बाद मैं अपने सॉर्टिंग एल्गोरिदम को सुधारना चाहता हूं (मैं इसे तेज़ी से बना देता हूं) लेकिन मैं यह सुनिश्चित करना चाहता हूं कि इसका व्यवहार अपेक्षित है, इसलिए मैं इसे मूल परीक्षणों के साथ फिर से जांचना चाहता हूं।

है यही कारण है कि मैं क्या करना चाहते हैं, हो सकता है वहाँ कोई समाधान नहीं है, मुझे आशा है कि कोई मुझे मदद मिल सकती है।

जवाब पसंद के बाद संपादित करें। मैंने रॉडनी का जवाब चुना क्योंकि उसका समाधान मैंने अपनाया है: एक स्टैंडअलोन सहायक वर्ग मेरी मदद करता है (यह एक सहायक है!) उप-विधियों के बारे में स्पष्ट रूप से देखने के लिए और यह मुझे परीक्षण करने की क्षमता भी देता है।

+0

मैं एक बार जब आप इंटरफ़ेस प्रकार है, तो आप समस्याओं के बिना अपने को लागू करने कोड का परीक्षण कर सकते ग्रहण टैग हटा दिया क्योंकि यह समस्या इसके लिए विशिष्ट नहीं है। –

उत्तर

10

फिलिपो, मैं समस्या के साथ और कुछ उत्तरों के साथ आपकी निराशा को समझता हूं। जब मैंने पहली बार जुनीट का उपयोग शुरू किया था, तो मैं भी निजी कोड का परीक्षण करना चाहता था, और मैंने सोचा कि यह गुरुओं के मूर्खतापूर्ण है कि यह एक बुरा विचार था।

बाहर कर देता है वे सही थे (आश्चर्य!), लेकिन लेखन के बाद ही काफी कुछ परीक्षण मैं समझता था कि क्यों। आप मुझे एक उचित स्टैंडअलोन वर्ग में Nested होगा एक ही प्रक्रिया के माध्यम से जाने की जरूरत हो सकती है, लेकिन आप अंत में अपनी स्थिति में

वैसे ही निष्कर्ष ;-) करने के लिए आ जाएगा,,, संभवतः एक अलग पैकेज में स्पष्ट बनाने के लिए कि यह एक सहायक वर्ग है। फिर मैं किसी अन्य परीक्षण से स्वतंत्र, सीधे इसके लिए परीक्षण लिखूंगा।

फिर मैं NewStyle के लिए परीक्षण लिखूंगा और केवल NewStyle के व्यवहार पर ध्यान केंद्रित करूंगा।

(काफी शायद मैं भी NewStyle में Nested बल्कि NewStyle भीतर यह instantiating से डालेगी -। परीक्षा में यानी यह NewStyle के निर्माता के लिए एक तर्क बनाने

फिर जब मैं NewStyle के लिए परीक्षण लिखने मैं था भी Nested का एक उदाहरण में गुजरती हैं और पर ले जाने के। अगर मैं विशेष रूप से मुश्किल महसूस किया है, मैं Nested से बाहर एक अंतरफलक बनाएंगे, और एक दूसरे कार्यान्वयन बनाते हैं, और परीक्षण के साथ NewStyle।)

+0

+1 पर विचार करें क्योंकि आपका समाधान वही है जो मैंने वर्तमान में अपनाया है (स्टैंडअलोन सहायक वर्ग) –

16

आप केवल वर्गों के सार्वजनिक इंटरफ़ेस, नहीं निजी सदस्यों या निजी इनर क्लासों का परीक्षण करना चाहिए। निजी सदस्य कार्यान्वयन विवरण के लिए हैं, केवल कक्षा के सार्वजनिक तरीकों (प्रत्यक्ष या अप्रत्यक्ष रूप से) द्वारा उपयोग किए जाते हैं। तो आप इन अप्रत्यक्ष रूप से इन्हें अपने कॉलर विधियों के माध्यम से परीक्षण कर सकते हैं। यदि आपको लगता है कि आपके पास उन यूनिट परीक्षणों में पर्याप्त ग्रैन्युलरिटी नहीं है, या आप जिन परिणामों में रुचि रखते हैं उनमें से कुछ (कुछ) को समझ नहीं सकते हैं, तो शायद यह आपके डिज़ाइन के साथ समस्या का संकेत दे सकता है: कक्षा बहुत बड़ी हो सकती है बहुत अधिक करने के लिए, इस प्रकार इसकी कुछ कार्यक्षमताओं को एक अलग वर्ग में निकालने की आवश्यकता हो सकती है, जहां इसे सीधे इकाई परीक्षण किया जा सकता है।

वर्तमान उदाहरण में, यदि भीतरी वर्ग ही कोड का एक बहुत कुछ शामिल है, तो आप बस इसे एक शीर्ष स्तर वर्ग में बदल सकता है, तो आप इकाई अपने तरीकों सीधे परीक्षण कर सकते हैं।

(Btw अपने भीतर वर्ग static होना चाहिए अगर यह संलग्नित क्लास उदाहरण का उल्लेख करने की जरूरत नहीं है।)

+0

हाय, उत्तर के लिए धन्यवाद। मैंने पहले से ही आपके जैसे कई उत्तर पढ़े हैं, लेकिन यह मेरे लिए अर्थ स्पष्ट नहीं है। क्या आप बेहतर समझने में मेरी मदद कर सकते हैं? मेरे पास कोड का एक टुकड़ा है जिसका उपयोग केवल एक बार किया जाता है, लेकिन मुझे यह सत्यापित करने की आवश्यकता है कि क्या ऐसा करने की अपेक्षा की जाती है। क्या मैं इसे पूरा कर सकता हूं? परीक्षण मुझे एक अच्छा विकल्प लग रहा था। –

+0

@ फिलिपो, मेरा अपडेट देखें। परीक्षण वास्तव में एक अच्छा विकल्प है - उन परीक्षणों को लिखें जो आपके द्वारा आने वाले सभी विभिन्न उपयोग परिदृश्यों को कवर करते हैं। एक कोड कवरेज टूल आपको अवांछित कोड भागों को खोजने में मदद करता है। –

+1

@ स्टेटर स्थिर पर आपके सुझाव के बारे में: आंतरिक कक्षाएं स्थिर स्थानीय आंतरिक वर्ग संख्या –

1

आप बाहर से इन कक्षाओं में नहीं पहुँच सकते हैं, तो JUnit उन्हें परीक्षण नहीं कर सकते। आपके पास उनका परीक्षण करने के लिए चीजें सार्वजनिक होनी चाहिए।

+0

यह सही नहीं है। जेमॉकिट जैसे नकली ढांचे निजी आंतरिक कक्षाओं (साथ ही निजी विधियों और सदस्यों) को ठीक से संभाल सकते हैं। – jchilders

+1

जेमॉकिट सबसे अधिक संभावना शरारती चीजों के साथ प्रतिबिंब के साथ करता है, जो जूनिट नहीं करता है। –

+0

क्या आप जानते हैं कि JMockit (या समान ढांचे) स्थानीय आंतरिक कक्षाओं के भीतर तरीकों का परीक्षण कर सकते हैं? –

1

आप अपने कोड उलझी अधिक से बचना चाहिए सिर्फ इसलिए कि आप

अगर वे के तरीके हैं तरीकों

आपके मामले में का भी फैलाव आप तरीकों का परीक्षण कर सकते हैं होने पसंद नहीं है बाहरी वर्ग या यदि आपको पूरी तरह से आंतरिक कक्षा की आवश्यकता है तो इसे मुख्य एएलजी() विधि के बाहर रखें ताकि यह वैश्विक स्तर पर दिखाई दे।

public class NewStyle { 

    public int mainAlg() { 

     Nested n = new Nested(); 
     int x = n.subAlg01(); 
     int y = n.subAlg02(); 

     int z = x * y; 
     return z; 
    } 

    class Nested { 

     public int subAlg01() { 
      return 3; 

     } 

     public int subAlg02() { 
      return 5; 
     } 
    } 
} 

इस तो new NewStyle().new Nested().subAlg01();

+0

उत्तर के लिए धन्यवाद। मैंने इस समाधान की भी कोशिश की लेकिन मुझे कक्षा से देखकर, मुझे इससे भी कम पसंद है, मुझे अभी भी स्पष्ट दृश्य नहीं है कि उप-एल्ग्स मुख्य एल्गोरिदम का हिस्सा हैं और किसी और द्वारा इसका उपयोग नहीं किया जाता है। फिर भी यह परीक्षण की अनुमति देता है। –

+0

नया न्यू स्टाइल()। नया नेस्टेड()। SubAlg01(); क्या आपको यकीन है? मैंने इसे कभी नहीं देखा है .../ –

1

हम्म का उपयोग कर कहा जा सकता है, मुझे पता है कि ग्रूवी जैसी भाषाओं अक्सर जावा पर इकाई परीक्षण करने के लिए उपयोग किया जाता है, और पारदर्शी निजी क्षेत्रों और तरीकों का उपयोग कर सकते हैं .... लेकिन मुझे घोंसला वाले वर्गों के बारे में निश्चित नहीं है। मैं समझ सकता हूं कि आप इस तरह की चीज क्यों कर सकते हैं, लेकिन मैं वही स्थिति लेता हूं जो मैं परीक्षण गेटर्स और सेटर्स के साथ लेता हूं, उन्हें आपके सार्वजनिक तरीकों का परीक्षण करने के दुष्प्रभाव के रूप में परीक्षण किया जाना चाहिए, और यदि वे नहीं करते हैं इस तरह से परीक्षण करें, फिर वे वहां से क्यों शुरू कर रहे हैं?

1

मुद्दा आता है जब अपने भीतर वर्ग का व्यवहार wh का मुख्य हिस्सा होता है एक विधि में: कहें कि आपके पास एक विधि है जो किसी तीसरे ऑब्जेक्ट को चलाने योग्य है, जो एक आंतरिक वर्ग होता है जो वास्तव में एक अलग इकाई नहीं होनी चाहिए: इस मामले में, उचित इकाई परीक्षण को बहुत अधिक व्यायाम की आवश्यकता होती है उस तीसरे ऑब्जेक्ट को मजाक करके आंतरिक वर्ग ने कहा, और इसका परीक्षण करने के लिए तर्क कैप्चर का उपयोग करके यह करना चाहिए।

इस तरह के मुद्दे उन भाषाओं में बहुत आम हैं जिनके पास कार्यात्मक प्रोग्रामिंग के लिए अधिक समर्थन है, जहां परीक्षण तीसरे पक्षों को भेड़ का बच्चा परीक्षण करना बहुत जरूरी है।

लेकिन, जैसा कि पहले कहा गया था, यदि आपकी आंतरिक कक्षा का बाहरी पार्टी द्वारा कभी भी उपयोग नहीं किया जाता है, तो यह केवल एक कार्यान्वयन विस्तार है, और इसे अलग से परीक्षण करना उपयोगी नहीं है।

1

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

:

public interface Algorithm { 
    int subAlg01(); 
    int subAlg02(); 
} 

वर्ग:

public class NewStyle { 
    public int mainAlg() { 
     class Nested implements Algorithm { 

      public int subAlg01() { 
       return 3; 
      } 

      public int subAlg02() { 
       return 5; 
      } 
     } 
     Nested n = new Nested(); 
     int x = n.subAlg01(); 
     int y = n.subAlg02(); 
     int z = x * y; 
     return z; 
    } 
} 

परीक्षण:

public class NewStyleTest { 

    @Test 
    public void testLocal() throws ClassNotFoundException, 
      NoSuchMethodException, SecurityException, InstantiationException, 
      IllegalAccessException, IllegalArgumentException, 
      InvocationTargetException { 
     Class<?> forName = Class.forName("NewStyle$1Nested"); 
     Constructor<?> declaredConstructor = forName 
       .getDeclaredConstructor(NewStyle.class); 
     declaredConstructor.setAccessible(true); 
     Algorithm algorithm = (Algorithm) declaredConstructor 
       .newInstance(new NewStyle()); 

     assertEquals(algorithm.subAlg01(), 3); 
     assertEquals(algorithm.subAlg02(), 5); 
    } 
} 
संबंधित मुद्दे