एक निजी विधि को यूनिट टेस्ट के लिए सार्वजनिक करना ... अच्छा विचार है?


301

मॉडरेटर नोट: यहां पहले से ही 39 उत्तर पोस्ट किए गए हैं (कुछ हटा दिए गए हैं)। अपना उत्तर पोस्ट करने से पहले , विचार करें कि आप चर्चा में कुछ सार्थक जोड़ सकते हैं या नहीं। आप संभावना से अधिक दोहरा रहे हैं कि किसी और ने पहले ही कहा है।


मैं कभी-कभी अपने आप को एक कक्षा में सार्वजनिक करने के लिए एक निजी विधि बनाने की जरूरत महसूस करता हूं, इसके लिए कुछ यूनिट टेस्ट लिखने के लिए।

आमतौर पर ऐसा इसलिए होता है क्योंकि विधि में कक्षा में अन्य विधियों के बीच साझा किए गए तर्क होते हैं और यह तर्क को अपने दम पर परखने के लिए तीखा होता है, या कोई अन्य कारण संभव हो सकता है कि मैं समसामयिक धागों में प्रयुक्त तर्क का परीक्षण करना चाहता हूं ताकि थ्रेडिंग समस्याओं के बारे में चिंता किए बिना। ।

क्या अन्य लोग खुद को ऐसा करते हुए पाते हैं, क्योंकि मुझे वास्तव में ऐसा करना पसंद नहीं है ?? मुझे व्यक्तिगत रूप से लगता है कि बोनस एक विधि को सार्वजनिक करने की समस्याओं से परे है जो वास्तव में वर्ग के बाहर कोई सेवा प्रदान नहीं करता है ...

अपडेट करें

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

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


2
"यदि आप एक समर्थन उपकरण का समर्थन करने के लिए एक प्रणाली बदल रहे हैं", यदि आप बुरा व्यवहार करते हैं, तो "। खैर, हाँ, की तरह। लेकिन OTOH आपके सिस्टम स्थापित उपकरणों के साथ अच्छी तरह से काम नहीं करता है, शायद कुछ है प्रणाली के साथ गलत।
थिलो

1
इस डुप्लिकेट का कैसे नहीं है stackoverflow.com/questions/105007/do-you-test-pStreet-method ?
सांग्युन ली

1
उत्तर नहीं है, लेकिन आप हमेशा प्रतिबिंब द्वारा उन्हें एक्सेस कर सकते हैं।
ज़ेनो जूल

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

4
हाँ यही है। यूनिट परीक्षणों से इसे सुलभ बनाने के लिए एक विधि पैकेज-निजी (डिफ़ॉल्ट) दृश्यता देना पूरी तरह से स्वीकार्य है। अमरूद की तरह पुस्तकालय भी @VisibileForTestingइस तरह के तरीकों को बनाने के लिए एक एनोटेशन प्रदान करते हैं - मैं आपको ऐसा करने की सलाह देता हूं ताकि विधि के privateठीक न होने का कारण सही ढंग से प्रलेखित न हो।
बोरिस स्पाइडर

जवाबों:


186

नोट:
यह उत्तर मूल रूप से इस सवाल के लिए पोस्ट किया गया था कि क्या यूनिट परीक्षण कभी गेटर्स के माध्यम से निजी उदाहरण चर को उजागर करने का एक अच्छा कारण है? जो इस एक में विलय कर दिया गया था, इसलिए यह वहाँ प्रस्तुत usecase के लिए एक विशिष्ट हो सकता है।

एक सामान्य कथन के रूप में, मैं आमतौर पर "उत्पादन" कोड को फिर से तैयार करने के लिए हूं ताकि यह परीक्षण करना आसान हो सके। हालाँकि, मुझे नहीं लगता कि यह एक अच्छी कॉल होगी। एक अच्छी इकाई परीक्षण (आमतौर पर) को केवल अपने दृश्य व्यवहार के बारे में, वर्ग के कार्यान्वयन विवरणों की परवाह नहीं करनी चाहिए। परीक्षण के लिए आंतरिक स्टैक को उजागर करने के बजाय, आप यह परीक्षण कर सकते हैं कि कक्षा उन पृष्ठों को वापस लौटा देती है, जो आप कॉल करने के बाद first()या करने की अपेक्षा करते हैं last()

उदाहरण के लिए, इस छद्म कोड पर विचार करें:

public class NavigationTest {
    private Navigation nav;

    @Before
    public void setUp() {
        // Set up nav so the order is page1->page2->page3 and
        // we've moved back to page2
        nav = ...;
    }

    @Test
    public void testFirst() {
        nav.first();

        assertEquals("page1", nav.getPage());

        nav.next();
        assertEquals("page2", nav.getPage());

        nav.next();
        assertEquals("page3", nav.getPage());
    }

    @Test
    public void testLast() {
        nav.last();

        assertEquals("page3", nav.getPage());

        nav.previous();
        assertEquals("page2", nav.getPage());

        nav.previous();
        assertEquals("page1", nav.getPage());
    }
}

8
मैं आपके उत्तर से पूरी तरह सहमत हूँ। कई डेवलपर्स को डिफ़ॉल्ट एक्सेस संशोधक का उपयोग करने का प्रलोभन दिया जाएगा और उचित होगा कि अच्छे ओपन सोर्स फ्रेमवर्क इस रणनीति का उपयोग करें ताकि यह सही होना चाहिए। सिर्फ इसलिए कि आप का मतलब यह नहीं है कि आपको चाहिए। +1
CKing

6
यद्यपि अन्य लोगों ने उपयोगी अंतर्दृष्टि प्रदान की है, मेरा कहना है कि यह समाधान है जो मुझे इस समस्या के लिए सबसे उपयुक्त लगता है। यह परीक्षणों को पूरी तरह से अज्ञेय रखता है कि आंतरिक उद्देश्य कैसे प्राप्त किया जाता है। +10!
गीता न्हांग 'जूल

वैसे, क्या यह ठीक है कि @Mureinik द्वारा यहां दिए गए उदाहरण में, परीक्षण विधियां परीक्षण के दौरान वास्तविक विधि से अधिक को कवर करती हैं? उदाहरण के लिए, टेस्टफर्स्ट () अगले कॉल करता है (), जो वास्तव में परीक्षण के तहत विधि नहीं है, पहला () है। क्या यह केवल 4 परीक्षण विधियों को कवर करने वाली 1 परीक्षण विधि के लिए क्लीनर और स्पष्ट नहीं होगा?
गीता न्हांग 'जूल

1
हालांकि यह आदर्श है, ऐसे समय हैं जब आपको एक घटक की जांच करने की आवश्यकता होती है जो कि सही तरीके से ऐसा नहीं करता है कि यह सफल था। यह ब्लैक बॉक्स टेस्ट के लिए कठिन हो सकता है। कुछ समय के लिए आपको एक घटक का परीक्षण करना होगा।
पीटर लॉरी

1
सिर्फ यूनिट-परीक्षण के लिए गेटर्स बनाना? यह निश्चित रूप से OOP / ऑब्जेक्ट थिंकिंग के दाने के खिलाफ जाता है कि इंटरफ़ेस को व्यवहार को उजागर करना चाहिए, न कि डेटा को।
इंटेलीडाटा

151

व्यक्तिगत रूप से, मैं नहीं बल्कि इकाई परीक्षण सार्वजनिक एपीआई का उपयोग कर और मैं निश्चित रूप से कभी नहीं निजी विधि सार्वजनिक करना चाहते हैं सिर्फ परीक्षण करने के लिए आसान इसे बनाने के लिए।

यदि आप वास्तव में अलगाव में निजी पद्धति का परीक्षण करना चाहते हैं, तो जावा में आप ईजीमॉक / पॉवर्मॉक का उपयोग कर सकते हैं ताकि आप ऐसा कर सकें ।

आपको इसके बारे में व्यावहारिक होना चाहिए और आपको उन कारणों के बारे में भी पता होना चाहिए जिनकी वजह से परीक्षण करना मुश्किल है।

' परीक्षण सुनें ' - यदि परीक्षण करना कठिन है, तो क्या यह आपको अपने डिजाइन के बारे में कुछ बता रहा है? क्या आप इस बात के लिए रिफ्लेक्टर कर सकते हैं कि इस पद्धति के लिए एक परीक्षण तुच्छ होगा और आसानी से सार्वजनिक एपीआई के माध्यम से परीक्षण करके कवर किया जाएगा?

यहां बताया गया है माइकल पंख 'में क्या कहना है है प्रभावी ढंग से विरासत कोड का उपयोग करने "

"बहुत से लोग इस समस्या के आसपास पाने के लिए ओटी का पता लगाने में बहुत समय बिताते हैं ... असली जवाब यह है कि यदि आपके पास एक निजी विधि का परीक्षण करने का आग्रह है, तो विधि निजी नहीं होनी चाहिए; यदि विधि को सार्वजनिक किया जाए; आपको परेशान करता है, संभावना है, यह इसलिए है क्योंकि यह एक अलग पुनरावृत्ति का हिस्सा है; यह किसी अन्य वर्ग पर होना चाहिए। " [ एम। पंख द्वारा लिगेसी कोड (2005) के साथ प्रभावी ढंग से काम करना ]


5
इजीमॉक / पॉवर्ॉक के लिए +1 और कभी भी एक निजी विधि को सार्वजनिक न करें
लियोनार्ड ब्रूडिंग्स

51
+1 के लिए "परीक्षणों को सुनें"। यदि आपको एक निजी विधि का परीक्षण करने की आवश्यकता महसूस होती है, तो संभावना अच्छी है कि उस पद्धति में तर्क इतना जटिल है कि यह एक अलग सहायक वर्ग में होना चाहिए। तब आप सहायक वर्ग का परीक्षण कर सकते हैं।
फिल

2
'परीक्षण सुनो' नीचे प्रतीत होता है। यहाँ एक कैश्ड लिंक है: webcache.googleusercontent.com/…
Jess Telford

1
मैं @Phil (विशेषकर पुस्तक संदर्भ) से सहमत हूं, लेकिन मैं अक्सर खुद को विरासत कोड के साथ चिकन / अंडे की स्थिति में पाता हूं। मुझे पता है कि यह तरीका दूसरी कक्षा का है, हालांकि मैं पहली बार परीक्षण किए बिना 100% आरामदायक रिफैक्टिंग नहीं कर रहा हूं।
केविन

मैं डॉक्टर के पास। यदि आपको एक निजी विधि का परीक्षण करने की आवश्यकता है, तो यह संभवतः दूसरे वर्ग में होना चाहिए। आप ध्यान दें कि अन्य वर्ग / सहायक वर्ग कि निजी पद्धति सार्वजनिक / संरक्षित होने की संभावना है।
रुपये

67

जैसा कि दूसरों ने कहा है, यह कुछ हद तक निजी तरीकों की इकाई परीक्षण करने के लिए संदिग्ध है; इकाई सार्वजनिक इंटरफ़ेस का परीक्षण करती है, न कि निजी कार्यान्वयन विवरणों का।

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


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

लेकिन एक वर्ग निकालने और परीक्षण केवल इसका मतलब है कि आपके परीक्षण इस ज्ञान को खो देते हैं कि मूल वर्ग वास्तव में निकाले गए कोड का उपयोग कर रहा है। आप अपने परीक्षणों में इस अंतर को भरने की सलाह कैसे देते हैं? और अगर इसका उत्तर मूल वर्ग के सार्वजनिक इंटरफ़ेस को इस तरह से परखना है, जिससे निकाले गए तर्क का उपयोग किया जा सके, तो इसे पहले स्थान पर निकालने की जहमत क्यों उठाई जाए? (मेरा मतलब यहाँ टकराव की आवाज़ नहीं है, btw - मैंने हमेशा सोचा है कि लोग इस तरह के व्यापार को कैसे संतुलित करते हैं।)
मल रॉस

@ हम एक सहयोग परीक्षण होगा। दूसरे शब्दों में, नए वर्ग को सही ढंग से सत्यापित करने के लिए एक नकली का उपयोग किया गया था। नीचे मेरा जवाब देखें।
फिंगलास

क्या कोई ऐसा परीक्षण वर्ग लिख सकता है जो आंतरिक तर्क के साथ वर्ग से विरासत में मिला हो जिसे आप आंतरिक तर्क के परीक्षण के लिए उपयोग करने के लिए एक सार्वजनिक विधि का परीक्षण और उपलब्ध कराना चाहते हैं?
शॉलिंजर

1
@sholsinger: C # में एक सार्वजनिक वर्ग को आंतरिक वर्ग से विरासत में नहीं मिल सकता है।
एरिक लिपपर्ट

45

बहुत सारे उत्तर केवल सार्वजनिक इंटरफ़ेस का परीक्षण करने का सुझाव देते हैं, लेकिन IMHO यह अवास्तविक है - यदि कोई विधि ऐसा कुछ करती है जिसमें 5 चरण होते हैं, तो आप उन पाँच चरणों का अलग-अलग परीक्षण करना चाहेंगे, सभी एक साथ नहीं। इसके लिए सभी पाँच विधियों का परीक्षण करना होगा, जो (परीक्षण के अलावा) अन्यथा हो सकती हैं private

"निजी" विधियों का परीक्षण करने का सामान्य तरीका हर वर्ग को अपना इंटरफ़ेस देना है, और "निजी" तरीके बनाना है public, लेकिन उन्हें इंटरफ़ेस में शामिल नहीं करना है। इस तरह, उन्हें अभी भी परीक्षण किया जा सकता है, लेकिन वे इंटरफ़ेस को ब्लोट नहीं करते हैं।

हां, यह फ़ाइल- और वर्ग-ब्लोट में परिणाम देगा।

हाँ, यह बनाता है publicऔर privateनिर्दिष्ट करता है ।

हां, यह गधे में दर्द है।

यह दुर्भाग्य से, कोड परीक्षण करने के लिए हमारे द्वारा किए गए कई बलिदानों में से एक है । शायद एक भविष्य की भाषा (या सी # / जावा का एक भविष्य का संस्करण) में क्लास- और मॉड्यूल-परीक्षण क्षमता को और अधिक सुविधाजनक बनाने की विशेषताएं होंगी; लेकिन इस बीच, हमें इन हुप्स के माध्यम से कूदना होगा।


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


2
1 आधा के लिए अच्छा जवाब
cmcginty

7
+1: मेरे लिए सबसे अच्छा जवाब। यदि एक ऑटो निर्माता अपनी कार के एक हिस्से का परीक्षण उसी कारण से नहीं करता है, तो मुझे यकीन नहीं है कि कोई भी इसे खरीद लेगा। कोड के महत्वपूर्ण भाग का परीक्षण किया जाना चाहिए, भले ही हमें इसे सार्वजनिक रूप से बदलना चाहिए।
ताए-सुंग शिन

1
बहुत बढ़िया जवाब। आपके पास मेरा गर्म वोट है। मैंने एक उत्तर जोड़ा। यह आपकी रुचि हो सकती है।
davidxxx

29

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


+1, और एक
वास्तविक

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

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

6
@ कैसी: यदि निजी पद्धति का उपयोग सार्वजनिक इंटरफ़ेस द्वारा नहीं किया जाता है तो यह क्यों है?
थिलो

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

22

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

यह ध्यान में रखते हुए कि मैं आपको परीक्षण पर ध्यान केंद्रित करने का सुझाव देता हूं कि आपका अनुबंध अभी भी कोई फर्क नहीं पड़ता है कि आपके वर्ग में वर्तमान में आंतरिक कार्यान्वयन क्या है। आपके सार्वजनिक एपीआई की संपत्ति आधारित परीक्षण।


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

20

इसे पैकेज निजी बनाने के बारे में कैसे? फिर आपका परीक्षण कोड इसे (और आपके पैकेज में अन्य कक्षाएं) भी देख सकता है, लेकिन यह अभी भी आपके उपयोगकर्ताओं से छिपा हुआ है।

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

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


+1 यदि आपको अपने निजीकरण का परीक्षण करने की आवश्यकता है तो आप शायद एक वर्ग
jk

लापता वर्ग के लिए +1। खुशी है कि दूसरों को "सीधे आंतरिक" निशान पर कूदने के लिए नहीं दिखा।
फिंगलास

लड़का मुझे पैकेज निजी जवाब खोजने के लिए एक लंबा रास्ता तय करना पड़ा।
बिल K

17

अद्यतन : मैंने कई अन्य स्थानों में इस प्रश्न का अधिक विस्तारित और अधिक पूर्ण उत्तर जोड़ा है। यह मेरे ब्लॉग पर पाया जा सकता है

अगर मुझे कभी इसे जांचने के लिए कुछ सार्वजनिक करने की आवश्यकता होती है, तो यह आमतौर पर संकेत देता है कि परीक्षण के तहत प्रणाली एकल पुनरावृत्ति सिद्धांत का पालन ​​नहीं कर रही है । इसलिए एक लापता वर्ग है जिसे पेश किया जाना चाहिए। एक नए वर्ग में कोड निकालने के बाद, इसे सार्वजनिक करें। अब आप आसानी से परीक्षण कर सकते हैं, और आप SRP का अनुसरण कर रहे हैं। आपकी अन्य कक्षा को रचना के माध्यम से इस नए वर्ग को लागू करना है।

तरीकों को सार्वजनिक करना / लैंग्वेज ट्रिक का उपयोग करना जैसे कि कोडिंग कोडिंग टेस्टीलीज़ के लिए दृश्यमान कोड हमेशा एक अंतिम उपाय होना चाहिए।

उदाहरण के लिए:

public class SystemUnderTest
{
   public void DoStuff()
   {
      // Blah
      // Call Validate()
   }

   private void Validate()
   {
      // Several lines of complex code...
   }
}

सत्यापनकर्ता वस्तु को प्रस्तुत करके इसे रिफलेक्टर करें।

public class SystemUnderTest
{
    public void DoStuff()
    {
       // Blah
       validator.Invoke(..)
    }
}

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


1
मुझे व्यक्तिगत रूप से लगता है कि SRP को बहुत दूर तक ले जाया जा सकता है, उदाहरण के लिए यदि मैं एक खाता सेवा लिखता हूं जो किसी एप्लिकेशन में खातों को अपडेट / बनाने / हटाने से संबंधित है, तो क्या आप मुझे बता रहे हैं कि आपको प्रत्येक ऑपरेशन के लिए एक अलग वर्ग बनाना चाहिए? और उदाहरण के लिए सत्यापन के बारे में क्या, यह वास्तव में किसी अन्य वर्ग के लिए सत्यापन तर्क को निकालने के लायक है जब इसका उपयोग कहीं और कभी नहीं किया जाएगा? imo जो कोड को कम पठनीय बनाता है, कम संक्षिप्त करता है और आपके आवेदन को शानदार वर्गों के साथ पैक करता है!
jcvandan

1
यह सब परिदृश्य पर निर्भर करता है। एक व्यक्ति की "एक काम करने की" परिभाषा, माताओं के लिए भिन्न हो सकती है। अपने लिए इस मामले में, स्पष्ट रूप से आप जिस निजी कोड का परीक्षण करना चाहते हैं वह जटिल है / सेट करने के लिए दर्द। जिस तथ्य को आप परखना चाहते हैं, यह साबित करता है कि यह बहुत अधिक कर रहा है। इसलिए हाँ, एक नई वस्तु का होना आदर्श होगा।
फिंगलास

1
अपने कोड को कम पठनीय बनाने के लिए मैं दृढ़ता से असहमत हूं। सत्यापन के लिए एक वर्ग होने से दूसरे ऑब्जेक्ट में एम्बेडेड सत्यापन होने की तुलना में पढ़ना आसान है। आपके पास अभी भी समान मात्रा में कोड है, यह सिर्फ एक बड़े वर्ग में नहीं है। मैं बल्कि कई वर्ग है जो एक बड़ी कक्षा की तुलना में बहुत अच्छी तरह से एक काम करना चाहते हैं।
फिंगलास

4
@dormisher, आपकी खाता सेवा के बारे में, SRP को "बदलने का एकल कारण" मानते हैं। यदि आपके CRUD ऑपरेशन स्वाभाविक रूप से एक साथ बदलेंगे, तो वे SRP में फिट होंगे। आम तौर पर, आप इसे बदल देंगे क्योंकि डेटाबेस स्कीमा बदल सकता है, जो स्वाभाविक रूप से सम्मिलित और अद्यतन को प्रभावित करेगा (हालांकि शायद हमेशा नहीं हटाएं)।
एंथनी Pegram

@finglas आप इस बारे में क्या सोचते हैं: stackoverflow.com/questions/29354729/… । मुझे निजी पद्धति का परीक्षण करने का मन नहीं है, इसलिए शायद मुझे इसे एक कक्षा में अलग नहीं करना चाहिए, लेकिन इसका उपयोग 2 अन्य सार्वजनिक तरीकों में किया जा रहा है, इसलिए मैं दो बार एक ही तर्क का परीक्षण करूंगा।
रोड्रिगो रुइज़

13

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


11

एक उपयोगिता वर्ग में ढेर प्रबंधन एल्गोरिदम को विभाजित क्यों नहीं किया गया? उपयोगिता वर्ग ढेर का प्रबंधन कर सकता है और सार्वजनिक एक्सेसर्स प्रदान कर सकता है। इसके यूनिट परीक्षणों को कार्यान्वयन विवरण पर ध्यान केंद्रित किया जा सकता है। एल्गोरिथ्म ट्रिकी क्लासेज के लिए डीप टेस्ट एज केस को कम करने और कवरेज सुनिश्चित करने में बहुत मददगार होते हैं।

फिर आपका वर्तमान वर्ग किसी भी कार्यान्वयन विवरण को उजागर किए बिना उपयोगिता वर्ग को स्पष्ट रूप से सौंप सकता है। इसके परीक्षण पृष्ठांकन आवश्यकता से संबंधित होंगे जैसा कि अन्य लोगों ने सिफारिश की है।


10

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


10

निजी तरीकों को आमतौर पर "सहायक" विधियों के रूप में उपयोग किया जाता है। इसलिए वे केवल मूल मूल्यों को वापस करते हैं और कभी भी वस्तुओं के विशिष्ट उदाहरणों पर काम नहीं करते हैं।

यदि आप उनका परीक्षण करना चाहते हैं तो आपके पास कुछ विकल्प हैं।

  • प्रतिबिंब का उपयोग करें
  • तरीकों पैकेज का उपयोग दे

वैकल्पिक रूप से आप सहायक विधि के साथ एक नई विधि को एक सार्वजनिक विधि के रूप में बना सकते हैं यदि यह एक नए वर्ग के लिए एक अच्छा उम्मीदवार है।

इस पर यहाँ बहुत अच्छा लेख है


1
निष्पक्ष टिप्पणी। सिर्फ एक विकल्प था, शायद एक बुरा।
adamjmarkham

@Finglas प्रतिबिंब का उपयोग कर निजी कोड का परीक्षण क्यों एक बुरा विचार है?
अंशुल

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

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

1
@Finglas परीक्षण कार्यान्वयन विवरण गलत नहीं है। उस पर आपका रुख है, लेकिन यह एक व्यापक रूप से बहस का विषय है। आंतरिक परीक्षण करना आपको कुछ फायदे देता है, भले ही वे पूर्ण कवरेज के लिए आवश्यक न हों। आपके परीक्षण अधिक केंद्रित हैं क्योंकि आप सार्वजनिक API से जाने के बजाय सीधे निजी विधियों का परीक्षण कर रहे हैं, जो आपके परीक्षण को भ्रमित कर सकता है। नकारात्मक परीक्षण आसान है क्योंकि आप मैन्युअल रूप से निजी सदस्यों को अमान्य कर सकते हैं और सुनिश्चित कर सकते हैं कि असंगत आंतरिक स्थिति के जवाब में सार्वजनिक एपीआई उचित त्रुटियां देता है। और भी उदाहरण हैं।
अंशुल

9

यदि आप C # का उपयोग कर रहे हैं तो आप विधि को आंतरिक बना सकते हैं। इस तरह आप सार्वजनिक API को प्रदूषित नहीं करते हैं।

फिर dll में विशेषता जोड़ें

[असेंबली: इंटरनैल्सविजेल्टो ("MyTestAssembly")]

अब सभी तरीके आपके MyTestAssembly प्रोजेक्ट में दिखाई दे रहे हैं। शायद एकदम सही नहीं, लेकिन बेहतर है कि निजी पद्धति को सिर्फ इसे परखने के लिए सार्वजनिक किया जाए।


7

यदि आपको आवश्यकता हो तो निजी चर का उपयोग करने के लिए प्रतिबिंब का उपयोग करें।

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


एक शून्य विधि के साथ आप क्या करेंगे?
इंटेलीडाटा

@IntelliData निजी चर का उपयोग करने के लिए प्रतिबिंब का उपयोग करें यदि आपको आवश्यकता है।
डैनियल एलेक्सी

6

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

इसके अलावा, विधि को सार्वजनिक घोषित करके, क्या कहना है कि छह महीने के समय में (यह भूल जाने के बाद कि विधि को सार्वजनिक करने का एकमात्र कारण परीक्षण के लिए है) कि आप (या यदि आपने परियोजना को सौंप दिया है) तो किसी ने पूरी तरह से जीता 'इसका उपयोग न करें, संभावित अनपेक्षित परिणामों और / या रखरखाव दुःस्वप्न के कारण।


1
क्या होगा यदि वर्ग एक सेवा अनुबंध का कार्यान्वयन है और इसका उपयोग केवल इंटरफ़ेस के माध्यम से किया जाता है - इस तरह भले ही निजी पद्धति को सार्वजनिक किया गया हो, इसे वैसे भी नहीं कहा जाएगा क्योंकि यह दृश्यमान नहीं है
jcvandan

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

इसके अलावा, अगर यह सुनिश्चित करने का एकमात्र तरीका है कि परीक्षण कवरेज में एक निजी पद्धति के अंदर हर किनारे का मामला शामिल है, तो इसे सीधे कॉल करें, यह संकेत हो सकता है कि वर्ग जटिलता वारंट इसे सरल बनाने के लिए रिफैक्टिंग करता है।
बेनी

@dormisher - यदि वर्ग का उपयोग केवल इंटरफ़ेस के माध्यम से किया जाता है, तो आपको केवल यह जांचने की आवश्यकता है कि सार्वजनिक इंटरफ़ेस विधि सही तरीके से व्यवहार करती है। यदि सार्वजनिक तरीके वे करते हैं जो वे करने के लिए हैं, तो आप निजी लोगों की परवाह क्यों करते हैं?
आंद्रेज डॉयल

@Andrzej - मुझे लगता है कि मुझे वास्तव में नहीं होना चाहिए, लेकिन ऐसी स्थितियां हैं जहां मेरा मानना ​​है कि यह वैध हो सकता है, उदाहरण के लिए, एक निजी विधि जो मॉडल स्थिति को मान्य करती है, यह इस तरह से एक विधि का परीक्षण करने के लायक हो सकती है - लेकिन इस तरह की विधि के माध्यम से परीक्षण योग्य होना चाहिए सार्वजनिक इंटरफ़ेस वैसे भी
jcvandan

6

इकाई परीक्षण के संदर्भ में, आपको निश्चित रूप से अधिक तरीके नहीं जोड़ने चाहिए; मेरा मानना ​​है कि आप बेहतर first()तरीके से अपनी विधि के बारे में एक टेस्ट केस करेंगे, जिसे प्रत्येक टेस्ट से पहले बुलाया जाएगा; तो आप कई बार फोन कर सकते हैं - next(), previous()और last()अगर परिणामों आपकी अपेक्षाओं से मेल देखने के लिए। मुझे लगता है कि यदि आप अपनी कक्षा में (केवल परीक्षण उद्देश्यों के लिए) अधिक विधियाँ नहीं जोड़ते हैं, तो आप परीक्षण के "ब्लैक बॉक्स" सिद्धांत से चिपके रहेंगे;


5

पहले देखें कि क्या विधि को किसी अन्य वर्ग में निकाला जाना चाहिए और सार्वजनिक किया जाना चाहिए। अगर ऐसा नहीं है, तो इसे पैकेज संरक्षित करें और जावा में एनोटेट के साथ @VoiceForTesting


5

अपने अद्यतन में आप कहते हैं कि सार्वजनिक API का उपयोग करके परीक्षण करना अच्छा है। यहां वास्तव में दो स्कूल हैं।

  1. ब्लैक बॉक्स परीक्षण

    ब्लैक बॉक्स स्कूल का कहना है कि कक्षा को एक ब्लैक बॉक्स माना जाना चाहिए जो कि कोई भी इसके अंदर कार्यान्वयन को नहीं देख सकता है। इसका परीक्षण करने का एकमात्र तरीका सार्वजनिक एपीआई के माध्यम से है - जैसे कक्षा का उपयोगकर्ता इसका उपयोग कर रहा होगा।

  2. सफेद बॉक्स परीक्षण।

    श्वेत बॉक्स स्कूल वर्ग के कार्यान्वयन के बारे में ज्ञान का उपयोग करने के लिए स्वाभाविक रूप से सोचता है और फिर यह जानने के लिए कक्षा का परीक्षण करता है कि यह काम करना चाहिए।

मैं वास्तव में चर्चा में पक्ष नहीं ले सकता। मुझे लगा कि यह जानना दिलचस्प होगा कि कक्षा (या पुस्तकालय या जो कुछ भी) का परीक्षण करने के दो अलग-अलग तरीके हैं।


4

वास्तव में ऐसी स्थितियां हैं जब आपको ऐसा करना चाहिए (जैसे जब आप कुछ जटिल एल्गोरिदम को लागू कर रहे हैं)। बस इसे पैकेज-प्राइवेट करें और यह पर्याप्त होगा। लेकिन ज्यादातर मामलों में शायद आपके पास बहुत अधिक जटिल वर्ग होते हैं जिन्हें तर्क को अन्य वर्गों में विभाजित करने की आवश्यकता होती है।


4

निजी तरीके जिन्हें आप अलगाव में परीक्षण करना चाहते हैं एक संकेत है कि आपकी कक्षा में एक और "अवधारणा" दफन है। उस "अवधारणा" को अपनी कक्षा में निकालें और इसे एक अलग "इकाई" के रूप में परखें।

इस वीडियो पर एक नज़र डालें इस विषय पर एक बहुत ही दिलचस्प के लिए।


4

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

इसके बजाय आपको "उच्च परीक्षण" करना चाहिए। निजी पद्धति को कॉल करने वाली विधि का परीक्षण करें। लेकिन आपके परीक्षणों को आपके अनुप्रयोगों की आवश्यकताओं और आपके "कार्यान्वयन निर्णयों" का परीक्षण करना चाहिए।

उदाहरण के लिए (शारीरिक छद्म कोड यहाँ);

   public int books(int a) {
     return add(a, 2);
   }
   private int add(int a, int b) {
     return a+b;
   } 

इसके बजाय "जोड़ने" का परीक्षण करने का कोई कारण नहीं है आप इसके बजाय "पुस्तकों" का परीक्षण कर सकते हैं।

कभी भी अपने परीक्षणों को आपके लिए कोड डिज़ाइन निर्णय न दें। परीक्षण करें कि आपको अपेक्षित परिणाम मिले, न कि आपको वह परिणाम कैसे मिले।


1
"कभी भी अपने परीक्षणों को आपके लिए कोड डिज़ाइन निर्णय लेने न दें" - मुझे असहमत होना चाहिए। परीक्षण के लिए कठिन होना एक कोड गंध है। यदि आप इसका परीक्षण नहीं कर सकते, तो आपको कैसे पता चलेगा कि यह टूटा नहीं है?
अल्फ्रेड आर्मस्ट्रांग

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

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

यह समाधान पुस्तकों की तरह एक विधि के लिए अच्छा है जो एक मूल्य लौटाता है - आप रिटर्न प्रकार की जांच कर सकते हैं ; लेकिन आप एक शून्य विधि की जाँच कैसे करेंगे ?
इंटेलीडाटा

शून्य विधियाँ कुछ करती हैं या उन्हें अस्तित्व में रहने की आवश्यकता नहीं होती है। जो कुछ वे करते हैं, उसकी जाँच करें,
coteyr

2

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

वैकल्पिक रूप से, यदि यह कार्यक्षमता है जिसे आप अलग-अलग परीक्षण करना चाहते हैं, तो क्या यह आपके डिजाइन से गायब वस्तु का सुझाव नहीं देता है? हो सकता है कि आप इसे एक अलग परीक्षण योग्य वर्ग में रख सकते हैं ... फिर आपका मौजूदा वर्ग इस नए वर्ग की एक आवृत्ति को दर्शाता है।


2

मैं आमतौर पर परीक्षण कक्षाओं को उसी प्रोजेक्ट / असेंबली में परीक्षण के तहत कक्षाओं के रूप में रखता हूं।
इस तरह मुझे केवल जरूरत हैinternal फ़ंक्शन / कक्षाओं को परीक्षण योग्य बनाने के लिए दृश्यता की ।

यह कुछ हद तक आपके निर्माण की प्रक्रिया को जटिल करता है, जिसे परीक्षण कक्षाओं को फ़िल्टर करने की आवश्यकता होती है। मैं अपने सभी परीक्षण वर्गों का नामकरण करके इसे प्राप्त करता हूंTestedClassTest करके और उन वर्गों को फ़िल्टर करने के लिए एक regex का उपयोग करके ।

यह पाठ्यक्रम केवल आपके प्रश्न के C # / .NET भाग पर लागू होता है


2

मैं अक्सर एक विधि जोड़ूंगा validate, जैसे कुछ verify,check एक वर्ग के लिए, आदि, इतना है कि यह एक वस्तु की आंतरिक स्थिति का परीक्षण करने के कहा जा सकता है।

कभी-कभी इस पद्धति को एक ifdef ब्लॉक में लपेटा जाता है (मैं ज्यादातर C ++ में लिखता हूं) ताकि यह रिलीज के लिए संकलित न हो। लेकिन यह अक्सर मान्यताओं के तरीकों को प्रदान करने के लिए रिलीज़ में उपयोगी होता है जो प्रोग्राम के ऑब्जेक्ट ट्रीज़ की चीजों की जाँच करते हैं।


2

अमरूद में एक @VigureForTesting एनोटेशन है जो उन तरीकों को चिह्नित करने के लिए है, जिनके पास गुंजाइश (पैकेज या सार्वजनिक) है जो वे अन्यथा करेंगे। मैं एक ही बात के लिए एक @ टिप्पणी एनोटेशन का उपयोग करता हूं।

हालांकि सार्वजनिक एपीआई का परीक्षण किया जाना चाहिए, कभी-कभी यह सामान के लिए सुविधाजनक और समझदार होता है जो आम तौर पर सार्वजनिक नहीं होगा।

कब:

  • एक वर्ग को बहुत कम पठनीय बनाया जाता है, जिसे टोटो में, कई वर्गों में तोड़कर,
  • बस इसे और अधिक परीक्षण योग्य बनाने के लिए,
  • और सराय में कुछ परीक्षण पहुँच प्रदान करने का काम करेगा

ऐसा लगता है जैसे धर्म ट्रम्पिंग इंजीनियरिंग है।


2

मैं आमतौर पर उन तरीकों को छोड़ता हूं protectedऔर एक ही पैकेज (लेकिन किसी अन्य प्रोजेक्ट या स्रोत फ़ोल्डर में) में यूनिट टेस्ट देता हूं , जहां वे सभी संरक्षित तरीकों तक पहुंच सकते हैं क्योंकि क्लास लोडर उन्हें उसी नामस्थान के भीतर रखेगा।


2

नहीं, क्योंकि उस बिल्ली की त्वचा के बेहतर तरीके हैं।

कुछ यूनिट टेस्ट हार्नेस क्लास परिभाषा में मैक्रोज़ पर भरोसा करते हैं जो टेस्ट मोड में निर्मित होने पर हुक बनाने के लिए स्वचालित रूप से विस्तार करते हैं। बहुत सी शैली, लेकिन यह काम करता है।

एक आसान OO मुहावरा कुछ भी करना है जिसे आप "निजी" के बजाय "संरक्षित" का परीक्षण करना चाहते हैं। परीक्षण हार्नेस परीक्षण के तहत कक्षा से विरासत में मिलता है, और फिर सभी संरक्षित सदस्यों तक पहुंच सकता है।

या आप "दोस्त" विकल्प के लिए जाते हैं। व्यक्तिगत रूप से यह C ++ की विशेषता है मुझे कम से कम पसंद है क्योंकि यह एन्कैप्सुलेशन नियमों को तोड़ता है, लेकिन यह आवश्यक है कि C ++ कुछ सुविधाओं को कैसे लागू करता है, इसलिए हे हो।

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


2

.Net में एक विशेष वर्ग होता है जिसे PrivateObjectविशेष रूप से नियत किया जाता है ताकि आप किसी कक्षा के निजी तरीकों का उपयोग कर सकें।

MSDN पर या स्टैक ओवरफ़्लो पर इसके बारे में अधिक देखें

(मुझे आश्चर्य है कि किसी ने भी अब तक इसका उल्लेख नहीं किया है।)

ऐसी स्थितियां हैं, हालांकि यह पर्याप्त नहीं है, इस स्थिति में आपको प्रतिबिंब का उपयोग करना होगा।

फिर भी मैं निजी तरीकों का परीक्षण न करने की सामान्य सिफारिश का पालन करूंगा, हालांकि हमेशा की तरह अपवाद हैं।


1

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

यहां एक छोटा उदाहरण वर्ग है जिसमें एक निजी उदाहरण विधि है।

public class A {
    private void doSomething() {
        System.out.println("Doing something private.");
    }
}

और एक उदाहरण वर्ग जो निजी उदाहरण विधि को निष्पादित करता है।

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class B {
    public static final void main(final String[] args) {
        try {
            Method doSomething = A.class.getDeclaredMethod("doSomething");
            A o = new A();
            //o.doSomething(); // Compile-time error!
            doSomething.setAccessible(true); // If this is not done, you get an IllegalAccessException!
            doSomething.invoke(o);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }
}

बी को निष्पादित करना, प्रिंट करेगा Doing something private. यदि आपको वास्तव में इसकी आवश्यकता है, तो प्रतिबिंब का उपयोग निजी उदाहरण विधियों तक पहुंचने के लिए इकाई परीक्षणों में किया जा सकता है।


0

निजी तौर पर, निजी तरीकों का परीक्षण करते समय मेरे पास समान समस्याएं हैं और इसका कारण यह है कि कुछ परीक्षण उपकरण सीमित हैं। अगर आपकी ज़रूरत का जवाब नहीं है तो यह ज़रूरी है कि वे आपकी ज़रूरत के हिसाब से डिज़ाइन न करें। चूँकि आपका C # i के लिए पूछना अच्छे परीक्षण साधनों का प्रस्ताव नहीं कर सकता है, लेकिन जावा के लिए दो शक्तिशाली उपकरण हैं: TestNG और PowerMock, और आप .NET प्लेटफ़ॉर्म के लिए संबंधित परीक्षण उपकरण पा सकते हैं

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