आप निजी तरीकों का परीक्षण कैसे करते हैं?


479

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

ऐसा करने का सही तरीका क्या है?


3
मुझे कुछ याद आ रहा है, या शायद यह सिर्फ इतना है कि यह प्रश्न है, ठीक है ... pre-historicइंटरनेट के वर्षों में, लेकिन निजी तरीकों की इकाई परीक्षण अब आसान और सीधे दोनों है, विजुअल स्टूडियो आवश्यक होने पर आवश्यक सहायक कक्षाओं का उत्पादन करता है और स्निपेट्स के साथ परीक्षण तर्क को पूर्व-भरना सरल कार्य के लिए किसी की इच्छा के करीब हो सकता है। उदाहरण के लिए देखें। msdn.microsoft.com/en-us/library/ms184807%28VS.90%29.aspx
mjv

3
यह stackoverflow.com/questions/34571/… के निकट डुप्लिकेट लगता है ।
रायडवल

प्रश्नकर्ता दृश्य स्टूडियो
डेव

3
यूनिट टेस्ट इंटर्नल्स
Mark Seemann

जवाबों:


122

यदि आप .net का उपयोग कर रहे हैं, तो आपको InternalsVoubleToAttribute का उपयोग करना चाहिए ।


86
छी। यह आपके जारी किए गए विधानसभाओं में संकलित हो जाता है।
जय

14
@Jay - एक का उपयोग नहीं कर सकता है #if DEBUGचारों ओर InternalsVisibleToयह नहीं रिलीज कोड पर लागू करने के लिए विशेषता?
एमपॉन्टिलो

20
@ माइक, आप कर सकते थे, लेकिन तब आप केवल डिबग कोड पर इकाई परीक्षण चला सकते हैं, रिलीज़ कोड नहीं। चूंकि रिलीज़ कोड अनुकूलित है, आप अलग-अलग व्यवहार और अलग-अलग समय देख सकते हैं। मल्टीथ्रेडेड कोड में इसका मतलब है कि आपकी इकाई परीक्षण उचित रूप से दौड़ की स्थिति का पता नहीं लगा पाएंगे। बेहतर यह है कि नीचे दिए गए @ AmpriseSaint के सुझाव के माध्यम से प्रतिबिंब का उपयोग करें या अंतर्निहित PrivateObject / PrivateType का उपयोग करें। यह आपको रिलीज़ बिल्ड में निजीकरण देखने के लिए अनुमति देता है, यह मानते हुए कि आपका टेस्ट हार्नेस पूरे विश्वास के साथ चल रहा है (जो MSTest स्थानीय रूप से चल रहा है)
Jay

121
मैं क्या खो रहा हूँ? जब यह वास्तव में निजी तरीकों के परीक्षण के विशिष्ट प्रश्न का उत्तर नहीं देता है तो यह स्वीकृत उत्तर क्यों होगा? इंटरनल्सविजनल्टो केवल आंतरिक के रूप में चिह्नित तरीकों को उजागर करता है और ओपी द्वारा अनुरोध किए गए निजी के रूप में चिह्नित नहीं है (और कारण मैं यहां उतरा)। मुझे लगता है कि मुझे PrivateObject का उपयोग जारी रखने की आवश्यकता है जैसा कि सेवन ने उत्तर दिया है?
डैरेन लुईस

6
@ मुझे पता है कि यह थोड़ा देर से आने वाला है, लेकिन एक विकल्प यह है कि माइक जैसा कुछ #if RELEASE_TESTइधर-उधर इस्तेमाल किया जाए InternalsVisibleTo, और आपके रिलीज़ बिल्ड कॉन्फ़िगरेशन की एक प्रतिलिपि बनाते हैं जो परिभाषित करता है RELEASE_TEST। आपको अपने रिलीज़ कोड का अनुकूलन के साथ परीक्षण करना है, लेकिन जब आप वास्तव में रिलीज़ के लिए निर्माण करते हैं, तो आपके परीक्षण छोड़ दिए जाएंगे।
शाज़ जूल

349

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

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

38
विकल्प 2 बनाता है इकाई परीक्षणों को फ़ंक्शन के अंतर्निहित कार्यान्वयन का ज्ञान होना चाहिए। मुझे ऐसा करना पसंद नहीं है। मुझे आमतौर पर लगता है कि यूनिट परीक्षणों को कार्यान्वयन के बारे में कुछ भी ग्रहण किए बिना फ़ंक्शन का परीक्षण करना चाहिए।
हेमीज़

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

30
यदि आप कार्यान्वयन को बदलते हैं , तो परीक्षणों को तोड़ना चाहिए । टीडीडी का मतलब होगा पहले परीक्षणों को बदलना।
सलके

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

26
भोलापन के लिए माफी (अभी तक परीक्षण के साथ बहुत अनुभव नहीं है), लेकिन अपने आप ही प्रत्येक कोड मॉड्यूल का परीक्षण करने के लिए इकाई परीक्षण का विचार नहीं है? मुझे वास्तव में समझ नहीं आया कि निजी तरीकों को इस विचार से बाहर क्यों रखा जाना चाहिए।
ओमिल

118

निजी तरीकों का परीक्षण करना उपयोगी नहीं हो सकता है। हालांकि, मैं भी कभी-कभी परीक्षण विधियों से निजी तरीकों को कॉल करना पसंद करता हूं। परीक्षण डेटा उत्पादन के लिए कोड दोहराव को रोकने के लिए अधिकांश समय ...

Microsoft इसके लिए दो तंत्र प्रदान करता है:

पहुंचकर्ता

  • गोटो को डेफिनिशन का सोर्स कोड
  • कक्षा के नाम पर राइट-क्लिक करें
  • "निजी एक्सेसर बनाएँ" चुनें
  • वह प्रोजेक्ट चुनें जिसमें एक्सेसर बनाया जाना चाहिए => आप foo_accessor नाम के साथ एक नया वर्ग समाप्त करेंगे। यह वर्ग गतिशील रूप से संकलन के दौरान उत्पन्न होगा और उपलब्ध सभी सदस्यों को निजीकृत करेगा।

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

PrivateObject क्लास Microsoft.VisualStudio.TestTools.UnitTestingP.POOject का उपयोग करने का दूसरा तरीका है

// Wrap an already existing instance
PrivateObject accessor = new PrivateObject( objectInstanceToBeWrapped );

// Retrieve a private field
MyReturnType accessiblePrivateField = (MyReturnType) accessor.GetField( "privateFieldName" );

// Call a private method
accessor.Invoke( "PrivateMethodName", new Object[] {/* ... */} );

2
आप निजी स्थिर तरीकों को कैसे लागू करते हैं?
स्टुपेरयूजर


3
निजी तरीकों के परीक्षण की पहुंच विधि को वीएस 2011 के बाद से हटा दिया जा रहा है। blogs.msdn.com/b/visualstudioalm/archive/2012/03/08/…
संजीत मिश्रा

1
डॉक्स माइक्रोसॉफ्ट की वेबसाइट पर पाया पढ़ना यहाँ मैं PrivateObject वर्ग का कोई उल्लेख बहिष्कृत किया जा रहा नहीं दिख रहा। मैं MSVS 2013 का उपयोग कर रहा हूं और यह उम्मीद के मुताबिक काम करता है।
stackunderflow

3
@RyanGates आपके द्वारा संदर्भित साइट पर पहला समाधान बताता है कि निजी सदस्यों तक पहुँचने का समाधान "अपने कोड में आंतरिक और निजी APIs तक पहुँचने में सहायता करने के लिए PrivateObject वर्ग का उपयोग करना है। यह Microsoft.Visualityudio.QualityTools.UnitTestFramework में पाया जाता है। dll असेंबली। "
stackunderflow

78

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

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


20
मुझे डर है कि मैं अब भी आपसे असहमत हूं। प्रत्येक घटक को एक ब्लैक बॉक्स के रूप में मानने से मॉड्यूल को समस्याओं के बिना / बाहर स्वैप किया जा सकता है। यदि आपके पास FooServiceऐसा करना है X, तो आपको केवल इस बात की परवाह करनी चाहिए कि यह वास्तव में Xअनुरोध किए जाने पर करता है । यह कैसे होता है यह बात नहीं होनी चाहिए। यदि इंटरफ़ेस (अप्रभावित) के माध्यम से कक्षा में समस्या नहीं है, तो यह अभी भी मान्य है FooService। यह एक समस्या यह है कि अगर है इंटरफेस के माध्यम से दिखाई, सार्वजनिक सदस्यों पर एक परीक्षण यह पता लगा लेगा। पूरे बिंदु यह होना चाहिए कि जब तक पहिया ठीक से मुड़ता है, तब तक इसे पहिया के रूप में इस्तेमाल किया जा सकता है।
बेसिक

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

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

6
@ डिमा निश्चित रूप से अगर वहाँ एक समस्या है PrivMethod, एक परीक्षण PubMethodजिस पर कॉल PrivMethodइसे उजागर करना चाहिए? जब आप अपने SimpleSmtpServiceको बदलते हैं तो क्या होता है GmailService? अचानक आपके निजी परीक्षण ऐसे कोड की ओर इशारा कर रहे हैं जो अब मौजूद नहीं है या शायद अलग तरीके से काम करता है और विफल हो जाएगा, भले ही एप्लिकेशन पूरी तरह से डिज़ाइन के अनुसार काम कर सकता है। यदि कोई जटिल प्रसंस्करण है जो दोनों ईमेल भेजने वालों पर लागू होगा, तो शायद ऐसा होना चाहिए EmailProcessorजिसका उपयोग दोनों द्वारा किया जा सकता है और अलग से परीक्षण किया जा सकता है?
बेसिक

2
@miltonb हम इसे विभिन्न विकास शैलियों से देख रहे होंगे। इन्टर्ल्स WRT, मैं उन्हें परीक्षण करने के लिए इकाई नहीं करते हैं। यदि कोई समस्या है (इंटरफ़ेस परीक्षणों द्वारा पहचानी गई है), तो डिबगर को संलग्न करके या तो ट्रैक करना आसान है या वर्ग बहुत जटिल है और इसे विभाजित किया जाना चाहिए (नए वर्ग इकाई के सार्वजनिक इंटरफ़ेस के साथ परीक्षण किया गया) IMHO
Basic

51

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

कक्षा:

...

protected void APrivateFunction()
{
    ...
}

...

परीक्षण के लिए उपवर्ग:

...

[Test]
public void TestAPrivateFunction()
{
    APrivateFunction();
    //or whatever testing code you want here
}

...

1
आप उस बच्चे की कक्षा को वास्तविक कक्षा में अव्यवस्थित करने के बजाय अपनी इकाई परीक्षा फ़ाइल में डाल सकते हैं। चालाक के लिए +1।
टिम एबेल

यदि संभव हो तो मैं हमेशा यूनिट परीक्षण परियोजना में सभी परीक्षण से संबंधित कोड डालता हूं। यह सिर्फ़ पेसो-कोड था।
जेसन जैक्सन

2
यह फ़ंक्शन निजी नहीं है, इसकी संरक्षित, शुद्ध परिणाम ... आपने अपना कोड कम सुरक्षित बनाया / उजागर किया बच्चे के प्रकार के निजी कार्यक्षमता
वार

22

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

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

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

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

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

यदि आपके पास विरासत का आवेदन है तो बेशक निजी तरीकों का परीक्षण सीधे अंतिम उपाय हो सकता है लेकिन मैं यह पसंद करूंगा कि विरासत कोड को बेहतर परीक्षण के लिए सक्षम बनाया जाए। माइकल फेदर ने इसी विषय पर एक महान पुस्तक लिखी है। http://www.amazon.co.uk/Working-Effectively-Legacy-Robert-Martin/dp/0131177052


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

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

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

@ बिग कहूना - यदि आपको लगता है कि ऐसा कोई मामला नहीं है जहां आपको निजी / यूनिट के तरीकों का परीक्षण करने की आवश्यकता है, तो आपने कभी भी बड़ी / जटिल पर्याप्त परियोजना के साथ काम नहीं किया है। ग्राहक की विशिष्ट मान्यताओं की तरह कई बार एक सार्वजनिक समारोह 20 लाइनों के साथ समाप्त होता है, जो कोड को अधिक पठनीय बनाने के लिए बहुत सरल निजी तरीकों को बुलाता है, लेकिन आपको अभी भी प्रत्येक व्यक्तिगत निजी विधि का परीक्षण करना होगा। 20 बार सार्वजनिक फ़ंक्शन का परीक्षण करना तब मुश्किल होता है जब यूनिट परीक्षण विफल हो जाता है।
पेड्रो.किड

1
मैं एक FTSE 100 कंपनी के लिए काम करता हूं। मुझे लगता है कि मैंने अपने समय में कई जटिल परियोजनाएं देखी हैं, धन्यवाद। यदि आपको उस स्तर पर परीक्षण करने की आवश्यकता है, तो अलग-अलग सहयोगियों के रूप में प्रत्येक निजी पद्धति को अलगाव में परीक्षण किया जाना चाहिए, क्योंकि इसका मतलब है कि उनके पास व्यक्तिगत व्यवहार है जो परीक्षण की आवश्यकता है। मुख्य मध्यस्थ वस्तु के लिए परीक्षण तब सिर्फ एक अंतःक्रियात्मक परीक्षण बन जाता है। यह सिर्फ सही रणनीति का परीक्षण करता है जिसे कहा जा रहा है। आपका परिदृश्य ऐसा लगता है जैसे प्रश्न में कक्षा SRP का अनुसरण नहीं कर रहा है। इसे बदलने का एक भी कारण नहीं है लेकिन 20 => एसआरपी उल्लंघन। GOOS पुस्तक या अंकल बॉब के बारे में पढ़ें। YMWV
बिग कहूना

17

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

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

इस प्रकार AccessPStreetWrapper का जन्म हुआ - http://amazedsaint.blogspot.com/2010/05/accesspStreetwrapper-c-40-dynamic.html - यह एक त्वरित आवरण वर्ग है जो C / 4.0 गतिशील सुविधाओं और प्रतिबिंब का उपयोग करके कार्य को आसान बना देगा।

आप जैसे आंतरिक / निजी प्रकार बना सकते हैं

    //Note that the wrapper is dynamic
    dynamic wrapper = AccessPrivateWrapper.FromType
        (typeof(SomeKnownClass).Assembly,"ClassWithPrivateConstructor");

    //Access the private members
    wrapper.PrivateMethodInPrivateClass();

12

वैसे आप निजी तरीके से दो तरीकों से टेस्ट कर सकते हैं

  1. आप PrivateObjectवर्ग का उदाहरण बना सकते हैं वाक्य रचना निम्नानुसार है

    PrivateObject obj= new PrivateObject(PrivateClass);
    //now with this obj you can call the private method of PrivateCalss.
    obj.PrivateMethod("Parameters");
  2. आप प्रतिबिंब का उपयोग कर सकते हैं।

    PrivateClass obj = new PrivateClass(); // Class containing private obj
    Type t = typeof(PrivateClass); 
    var x = t.InvokeMember("PrivateFunc", 
        BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Public |  
            BindingFlags.Instance, null, obj, new object[] { 5 });

अच्छा उत्तर, लेकिन # 1 के लिए आपका सिंटैक्स गलत है। आपको PrivateClassपहले एक उदाहरण की घोषणा करने और उस का उपयोग करने की आवश्यकता है। stackoverflow.com/questions/9122708/…
SharpC

10

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

आखिरकार, आप विशिष्ट कार्यान्वयन के बजाय अपनी कक्षा के व्यवहार का परीक्षण कर रहे हैं - आप पूर्व को बदले बिना बाद को बदल सकते हैं और आपके परीक्षण अभी भी पास होने चाहिए।


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

9

निजी तरीके 2 प्रकार के होते हैं। स्टेटिक प्राइवेट मेथड्स और नॉन स्टैटिक प्राइवेट मेथड्स (इंस्टैंस मेथड्स)। निम्नलिखित 2 लेख बताते हैं कि कैसे उदाहरणों के साथ निजी तरीकों का परीक्षण करना है।

  1. इकाई परीक्षण स्थैतिक निजी तरीके
  2. यूनिट टेस्टिंग नॉन स्टेटिक प्राइवेट मेथड्स

कुछ उदाहरण प्रदान करें, न केवल एक लिंक दें
13

कुरूप लगता है। कोई बात नहीं। एमएस से खराब समाधान। मैं अभी सकते मे हूँ !
alerya

निजी स्थिर तरीकों का परीक्षण करने का सबसे आसान तरीका
अनुदान

8

MS Test में एक अच्छी सुविधा है, जो VSCodeGenAccessors नामक एक फाइल बनाकर परियोजना में निजी सदस्यों और विधियों को उपलब्ध कराती है

[System.Diagnostics.DebuggerStepThrough()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TestTools.UnitTestGeneration", "1.0.0.0")]
    internal class BaseAccessor
    {

        protected Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject m_privateObject;

        protected BaseAccessor(object target, Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType type)
        {
            m_privateObject = new Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject(target, type);
        }

        protected BaseAccessor(Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType type)
            :
                this(null, type)
        {
        }

        internal virtual object Target
        {
            get
            {
                return m_privateObject.Target;
            }
        }

        public override string ToString()
        {
            return this.Target.ToString();
        }

        public override bool Equals(object obj)
        {
            if (typeof(BaseAccessor).IsInstanceOfType(obj))
            {
                obj = ((BaseAccessor)(obj)).Target;
            }
            return this.Target.Equals(obj);
        }

        public override int GetHashCode()
        {
            return this.Target.GetHashCode();
        }
    }

बेसएक्टर से प्राप्त होने वाली कक्षाओं के साथ

जैसे कि

[System.Diagnostics.DebuggerStepThrough()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TestTools.UnitTestGeneration", "1.0.0.0")]
internal class SomeClassAccessor : BaseAccessor
{

    protected static Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType m_privateType = new Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType(typeof(global::Namespace.SomeClass));

    internal SomeClassAccessor(global::Namespace.Someclass target)
        : base(target, m_privateType)
    {
    }

    internal static string STATIC_STRING
    {
        get
        {
            string ret = ((string)(m_privateType.GetStaticField("STATIC_STRING")));
            return ret;
        }
        set
        {
            m_privateType.SetStaticField("STATIC_STRING", value);
        }
    }

    internal int memberVar    {
        get
        {
            int ret = ((int)(m_privateObject.GetField("memberVar")));
            return ret;
        }
        set
        {
            m_privateObject.SetField("memberVar", value);
        }
    }

    internal int PrivateMethodName(int paramName)
    {
        object[] args = new object[] {
            paramName};
        int ret = (int)(m_privateObject.Invoke("PrivateMethodName", new System.Type[] {
                typeof(int)}, args)));
        return ret;
    }

8
यह फाइल केवल VS2005 में मौजूद होगी। 2008 में वे पर्दे के पीछे उत्पन्न हुए। और वे एक घृणित हैं। और संबंधित छाया कार्य एक बिल्ड सर्वर पर परतदार है।
बार्टनेल

इसके अलावा VS2012-2013 में एक्सेसरों को हटा दिया गया था।
ज़ेफन श्रोएडर

5

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

आप लेख यहाँ पा सकते हैं:

http://www.codeproject.com/KB/cs/testnonpublicmembers.aspx


4

उन्हें घोषित करें internal, और फिर InternalsVisibleToAttributeअपनी इकाई परीक्षण असेंबली को उन्हें देखने की अनुमति देने के लिए उपयोग करें।


11
मुझे इंटरनैटलविजिटो का उपयोग करना पसंद नहीं है क्योंकि मैंने एक कारण से विधि को निजी बना दिया है।
swilliams

4

मैं संकलक निर्देशों का उपयोग नहीं करता हूं क्योंकि वे चीजों को जल्दी से अव्यवस्थित करते हैं। इसे कम करने का एक तरीका यदि आपको वास्तव में उनकी आवश्यकता है तो उन्हें एक आंशिक वर्ग में रखना है और अपने निर्माण को अनदेखा करना है। उत्पादन संस्करण बनाते समय .cs फ़ाइल को।


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

4

आपको पहली बार अपने कोड के निजी तरीकों का परीक्षण नहीं करना चाहिए। आपको 'सार्वजनिक इंटरफ़ेस' या एपीआई, अपनी कक्षाओं की सार्वजनिक चीजों का परीक्षण करना चाहिए। API वे सभी सार्वजनिक विधियाँ हैं, जिन्हें आप बाहरी कॉलर्स के लिए उजागर करते हैं।

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

आपको इस कारण से InternalsVanishToAtrribute का उपयोग करने से बचना चाहिए।

यहाँ इयान कूपर द्वारा एक बड़ी बात की गई है जो इस विषय को शामिल करता है: इयान कूपर: टीडीडी, जहां यह सब गलत हुआ


3

कभी-कभी, निजी घोषणाओं का परीक्षण करना अच्छा हो सकता है। मौलिक रूप से, एक कंपाइलर में केवल एक सार्वजनिक तरीका होता है: कंपाइल (स्ट्रिंग आउटपुटफाइलनेम, पैरामस स्ट्रिंग [] sourceSileileNames)। मुझे यकीन है कि आप समझते हैं कि प्रत्येक "छिपी" घोषणाओं का परीक्षण किए बिना इस तरह की विधि का परीक्षण करना मुश्किल होगा!

इसलिए हमने आसान परीक्षण करने के लिए विज़ुअल टी # बनाया है। यह एक नि: शुल्क .NET प्रोग्रामिंग भाषा है (C # v2.0 संगत)।

हमने '.-' ऑपरेटर जोड़ा है। यह सिर्फ 'जैसा व्यवहार करता है।' ऑपरेटर, सिवाय आप अपने परीक्षण किए गए प्रोजेक्ट में कुछ भी बदले बिना अपने परीक्षणों से किसी भी छिपी घोषणा को एक्सेस कर सकते हैं।

हमारी वेब साइट पर एक नज़र डालें: इसे मुफ्त में डाउनलोड करें


3

मुझे आश्चर्य है कि किसी ने भी अभी तक यह नहीं कहा है, लेकिन मैंने जो समाधान काम किया है, वह है कि खुद को परखने के लिए कक्षा के अंदर एक स्थिर विधि बनाना। यह आपको परीक्षण करने के लिए सार्वजनिक और निजी सभी चीज़ों तक पहुँच प्रदान करता है।

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


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

यह आपको बाहरी रूप से परीक्षण करने से रोकता नहीं है ... बस स्थैतिक विधि को कॉल करें जो आपको पसंद है। कोड आधार भी गड़बड़ नहीं है ... आप तदनुसार विधि का नाम दें। मैं "रनटैस्ट" का उपयोग करता हूं, लेकिन कुछ भी समान काम करता है।
रब

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

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

3

मैं यहां एक स्पष्ट कोड उदाहरण बनाना चाहता हूं जिसे आप किसी भी वर्ग पर उपयोग कर सकते हैं जिसमें आप निजी पद्धति का परीक्षण करना चाहते हैं।

अपने परीक्षण के मामले में कक्षा में इन विधियों को शामिल करें और फिर उन्हें संकेत के अनुसार नियोजित करें।

  /**
   *
   * @var Class_name_of_class_you_want_to_test_private_methods_in
   * note: the actual class and the private variable to store the 
   * class instance in, should at least be different case so that
   * they do not get confused in the code.  Here the class name is
   * is upper case while the private instance variable is all lower
   * case
   */
  private $class_name_of_class_you_want_to_test_private_methods_in;

  /**
   * This uses reflection to be able to get private methods to test
   * @param $methodName
   * @return ReflectionMethod
   */
  protected static function getMethod($methodName) {
    $class = new ReflectionClass('Class_name_of_class_you_want_to_test_private_methods_in');
    $method = $class->getMethod($methodName);
    $method->setAccessible(true);
    return $method;
  }

  /**
   * Uses reflection class to call private methods and get return values.
   * @param $methodName
   * @param array $params
   * @return mixed
   *
   * usage:     $this->_callMethod('_someFunctionName', array(param1,param2,param3));
   *  {params are in
   *   order in which they appear in the function declaration}
   */
  protected function _callMethod($methodName, $params=array()) {
    $method = self::getMethod($methodName);
    return $method->invokeArgs($this->class_name_of_class_you_want_to_test_private_methods_in, $params);
  }

$ यह -> _ callMethod ('_ someFunctionName', सरणी (param1, param2, param3));

बस उस क्रम में पैरामीटर जारी करें जो वे मूल निजी फ़ंक्शन में दिखाई देते हैं


3

किसी के लिए भी जो बिना किसी डर और गड़बड़ी के निजी तरीकों को चलाना चाहता है। यह किसी भी इकाई परीक्षण ढांचे के साथ काम करता है, लेकिन पुराने पुराने प्रतिबिंब के अलावा कुछ भी नहीं।

public class ReflectionTools
{
    // If the class is non-static
    public static Object InvokePrivate(Object objectUnderTest, string method, params object[] args)
    {
        Type t = objectUnderTest.GetType();
        return t.InvokeMember(method,
            BindingFlags.InvokeMethod |
            BindingFlags.NonPublic |
            BindingFlags.Instance |
            BindingFlags.Static,
            null,
            objectUnderTest,
            args);
    }
    // if the class is static
    public static Object InvokePrivate(Type typeOfObjectUnderTest, string method, params object[] args)
    {
        MemberInfo[] members = typeOfObjectUnderTest.GetMembers(BindingFlags.NonPublic | BindingFlags.Static);
        foreach(var member in members)
        {
            if (member.Name == method)
            {
                return typeOfObjectUnderTest.InvokeMember(method, BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod, null, typeOfObjectUnderTest, args);
            }
        }
        return null;
    }
}

फिर अपने वास्तविक परीक्षणों में, आप ऐसा कुछ कर सकते हैं:

Assert.AreEqual( 
  ReflectionTools.InvokePrivate(
    typeof(StaticClassOfMethod), 
    "PrivateMethod"), 
  "Expected Result");

Assert.AreEqual( 
  ReflectionTools.InvokePrivate(
    new ClassOfMethod(), 
    "PrivateMethod"), 
  "Expected Result");

2

MbUnit को रिफ्लेक्टर नाम का एक अच्छा रैपर मिला।

Reflector dogReflector = new Reflector(new Dog());
dogReflector.Invoke("DreamAbout", DogDream.Food);

आप गुणों से मान भी सेट और प्राप्त कर सकते हैं

dogReflector.GetProperty("Age");

"टेस्ट प्राइवेट" के बारे में मैं मानता हूं कि .. एकदम सही दुनिया में। निजी इकाई परीक्षण करने का कोई मतलब नहीं है। लेकिन वास्तविक दुनिया में आप कोड को फिर से भरने के बजाय निजी परीक्षण लिखना चाह सकते हैं।


4
बस जानकारी के लिए, गैलियो / MbUnit v3.2 में Reflectorअधिक शक्तिशाली द्वारा प्रतिस्थापित किया गया है Mirror। ( gallio.org/wiki/doku.php?id=mbunit:mirror )
यान

2

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


2

मेरी राय में आपको केवल अपने क्लासेज़ के सार्वजनिक एपीआई का परीक्षण करना चाहिए।

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

एक अच्छा सार्वजनिक एपीआई क्लाइंट कोड के तत्काल लक्ष्य को हल करता है और उस लक्ष्य को पूरी तरह से हल करता है।


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

2

मैं PrivateObject क्लास का उपयोग करता हूं । लेकिन जैसा कि पहले उल्लेख किया गया है कि निजी तरीकों के परीक्षण से बचने के लिए बेहतर है।

Class target = new Class();
PrivateObject obj = new PrivateObject(target);
var retVal = obj.Invoke("PrivateMethod");
Assert.AreEqual(retVal);

2
CC -Dprivate=public

"CC" मेरे द्वारा उपयोग किए जाने वाले सिस्टम पर कमांड लाइन कंपाइलर है। -Dfoo=barके बराबर करता है #define foo bar। इसलिए, यह संकलन विकल्प प्रभावी रूप से सभी निजी सामानों को सार्वजनिक रूप से बदल देता है।


2
यह क्या है? क्या यह विजुअल स्टूडियो पर लागू होता है?
यशस्वी

"CC" मेरे द्वारा उपयोग किए जाने वाले सिस्टम पर कमांड लाइन कंपाइलर है। "-Dfoo = bar" "#define foo bar" के बराबर है। इसलिए, यह संकलन विकल्प प्रभावी रूप से सभी निजी सामानों को सार्वजनिक रूप से बदल देता है। हा-हा!
मार्क हैरिसन

Visual Studio में, अपने बिल्ड वातावरण में एक डिफाइन सेट करें।
मार्क हैरिसन

1

यहाँ एक उदाहरण है, पहला विधि हस्ताक्षर:

private string[] SplitInternal()
{
    return Regex.Matches(Format, @"([^/\[\]]|\[[^]]*\])+")
                        .Cast<Match>()
                        .Select(m => m.Value)
                        .Where(s => !string.IsNullOrEmpty(s))
                        .ToArray();
}

यहाँ परीक्षण है:

/// <summary>
///A test for SplitInternal
///</summary>
[TestMethod()]
[DeploymentItem("Git XmlLib vs2008.dll")]
public void SplitInternalTest()
{
    string path = "pair[path/to/@Key={0}]/Items/Item[Name={1}]/Date";
    object[] values = new object[] { 2, "Martin" };
    XPathString xp = new XPathString(path, values);

    PrivateObject param0 = new PrivateObject(xp);
    XPathString_Accessor target = new XPathString_Accessor(param0);
    string[] expected = new string[] {
        "pair[path/to/@Key={0}]",
        "Items",
        "Item[Name={1}]",
        "Date"
    };
    string[] actual;
    actual = target.SplitInternal();
    CollectionAssert.AreEqual(expected, actual);
}

1

ऐसा करने का एक तरीका यह है कि आपके पास protectedएक तरीका है और एक परीक्षण स्थिरता लिखें जो आपकी कक्षा को परीक्षण करने के लिए विरासत में मिले। इस तरह, आप न तो अपना तरीका बदल रहे हैं public, लेकिन आप परीक्षण को सक्षम करते हैं।


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

1

1) यदि आपके पास एक विरासत कोड है, तो निजी तरीकों का परीक्षण करने का एकमात्र तरीका प्रतिबिंब है।

2) यदि यह नया कोड है तो आपके पास निम्नलिखित विकल्प हैं:

  • प्रतिबिंब का उपयोग करें (जटिल करने के लिए)
  • एक ही क्लास में यूनिट टेस्ट लिखें (टेस्ट कोड भी होने से प्रोडक्शन कोड को बदसूरत बना देता है)
  • रिफैक्टर और विधि को किसी प्रकार के उपयोग वर्ग में सार्वजनिक करें
  • @VoiceForTesting एनोटेशन का उपयोग करें और निजी निकालें

मैं एनोटेशन विधि को पसंद करता हूं, सबसे सरल और कम से कम जटिल। एकमात्र मुद्दा यह है कि हमने दृश्यता बढ़ा दी है जो मुझे लगता है कि कोई बड़ी चिंता नहीं है। हमें हमेशा इंटरफ़ेस को कोडिंग करना चाहिए, इसलिए यदि हमारे पास एक इंटरफ़ेस MyService और एक कार्यान्वयन MyServiceImpl है तो हमारे पास संबंधित परीक्षण कक्षाएं हो सकती हैं जो MyServiceTest (परीक्षण इंटरफ़ेस विधियाँ) और MyServiceImplTest (परीक्षण निजी विधियाँ) हैं। सभी ग्राहकों को वैसे भी इंटरफ़ेस का उपयोग इस तरह से करना चाहिए, भले ही निजी पद्धति की दृश्यता बढ़ाई गई हो, यह वास्तव में कोई फर्क नहीं होना चाहिए।


1

डिबग-मोड में निर्माण के दौरान आप इसे सार्वजनिक या आंतरिक (इंटरनैशनलविजोरट्यूट के साथ) घोषित कर सकते हैं:

    /// <summary>
    /// This Method is private.
    /// </summary>
#if DEBUG
    public
#else
    private
#endif
    static string MyPrivateMethod()
    {
        return "false";
    }

यह कोड को ब्लॉट करता है, लेकिन यह privateएक रिलीज बिल्ड में होगा।


0

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

http://msdn.microsoft.com/en-us/library/bb385974.aspx


0

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


2
नहीं है, InternalsVisibleToAttributeकरता है नहीं की आवश्यकता होती है कि आपके विधानसभाओं दृढ़ता से नाम दिया। मैं वर्तमान में एक ऐसी परियोजना पर इसका उपयोग करता हूं जहां ऐसा नहीं है।
कोड़ी ग्रे

1
यह स्पष्ट करने के लिए: "वर्तमान विधानसभा और मित्र विधानसभा दोनों को अहस्ताक्षरित होना चाहिए, या दोनों को एक मजबूत नाम से हस्ताक्षरित होना चाहिए।" - MSDN से
हरि
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.