दिलचस्प पोस्ट
सूची को कैसे अच्छी तरह से मुद्रित करना है? Matplotlib 2 सबप्लॉट, 1 रंग बार एक नियमित सरणी का तत्व निकालें आर में सूचियों का सही उपयोग कैसे करें? मानक पायथन कक्षा (बाह्य पुस्तकालय का उपयोग किए बिना) का उपयोग कर छवि आकार कैसे प्राप्त करें? एएसएक्स का प्रयोग करके जेएसओएन को PHP पर भेजा जा रहा है Sendevent कमांड का उपयोग करके डिवाइस पर टच ईवेंट भेजने के लिए एडीबी का उपयोग कैसे करें? मैं 301 की रीडायरेक्ट के जरिए यूआरएल को कैसे स्थानांतरित कर सकता हूं और पेज की फेसबुक पसंद और ओपन ग्राफ़ की जानकारी को कैसे कायम कर सकता हूं? जमा करने के बाद JSF फॉर्म इनपुट मान साफ़ करें कैसे CodeIgniter के साथ WordPress टेम्पलेट को एकीकृत करने के लिए मैं Angular.js में अलग वातावरण कैसे कॉन्फ़िगर करूं? लैन फ़ंक्शन SQL सर्वर में रिक्त स्थान को शामिल नहीं करता है https के बिना क्रोम 47 में getUserMedia () प्राप्त करें कक्षाओं में अजगर सजावट एसक्यूएल में "@" चिन्ह क्या करता है?

आप कैसे यूनिट परीक्षण निजी विधियों कर सकते हैं?

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

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

Solutions Collecting From Web of "आप कैसे यूनिट परीक्षण निजी विधियों कर सकते हैं?"

आपको आंतरिकस्वास्थ्यताओटेटिविटी का उपयोग करना चाहिए।

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

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

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

माइक्रोसॉफ्ट इस के लिए दो तंत्र प्रदान करता है:

पहुंचकर्ता

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

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

निजी ऑब्जेक्ट क्लास माइक्रोसॉफ्ट का उपयोग करने का दूसरा तरीका है। विज़ुअल स्टूडियोटेस्ट टूल्सयूनिटटिस्टिंगनिजी ऑब्जेक्ट

 // 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[] {/* ... */} ); 

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

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

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

कक्षा:

 ... protected void APrivateFunction() { ... } ... 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

अच्छी तरह से आप यूनिट दो तरीकों से निजी विधि का परीक्षण कर सकते हैं

  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 }); 

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

 [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(); } } 

BaseAccessor से प्राप्त वर्गों के साथ

जैसे कि

 [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; } 

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

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

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

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

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

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

उन्हें internal घोषित करें, और फिर अपने यूनिट परीक्षण विधानसभा को देखने के लिए उन्हें आंतरिकक्षेत्र के लिए उपयोग करें।

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

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

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

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

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

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

आपको इस कारण से आंतरिकस्वास्थ्यताविराम का उपयोग करने से बचने चाहिए।

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

MbUnit को इस बुलाया परावर्तक के लिए एक अच्छा आवरण मिला।

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

आप गुणों से मूल्य निर्धारित और प्राप्त भी कर सकते हैं

 dogReflector.GetProperty("Age"); 

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

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

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

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

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

  /** * * @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); } 

$ the -> _ callMethod ('_ कुछ फल' नाम ', सरणी (पैरामीटर, परम 2, परम 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; } } 

Then in your actual tests, you can do something like this:

 Assert.AreEqual( ReflectionTools.InvokePrivate( typeof(StaticClassOfMethod), "PrivateMethod"), "Expected Result"); Assert.AreEqual( ReflectionTools.InvokePrivate( new ClassOfMethod(), "PrivateMethod"), "Expected Result"); 
 CC -Dprivate=public 

Here is good article about unit testing of private methods. But I'm not sure what's better, to make you application designed specially for testing(it's like creating tests for testing only) or use reflexion for testing. Pretty sure most of us will choose second way.

I use PrivateObject class. But as mentioned previously better to avoid testing private methods.

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

You could generate the test method for the private method from Visual studio 2008. When you create a unit test for a private method, a Test References folder is added to your test project and an accessor is added to that folder. The accessor is also referred to in the logic of the unit test method. This accessor allows your unit test to call private methods in the code that you are testing. For details have a look at

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

Also note that the InternalsVisibleToAtrribute has a requirement that your assembly be strong named , which creates it's own set of problems if you're working in a solution that had not had that requirement before. I use the accessor to test private methods. See this question that for an example of this.

Here's an example, first the method signature:

 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); } 

A way to do this is to have your method protected and write a test fixture which inherits your class to be tested. This way, you are nor turning your method public , but you enable the testing.

1) If you have a legacy code then the only way to test private methods is by reflection.

2) If it is new code then you have the following options:

  • Use reflection (to complicated)
  • Write unit test in the same class (makes the production code ugly by having test code also in it)
  • Refactor and make the method public in some kind of util class
  • Use @VisibleForTesting annotation and remove private

I prefer the annotation method, simplest and least complicated. The only issue is that we have increased the visibility which I think is not a big concern. We should always be coding to interface, so if we have an interface MyService and an implementation MyServiceImpl then we can have the corresponding test classes that is MyServiceTest (test interface methods) and MyServiceImplTest (test private methods). All clients should anyway be using the interface so in a way even though the visibility of the private method has been increased it should not really matter.

You could also declare it as public or internal (with InternalsVisibleToAttribute) while building in debug-Mode:

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

It bloats the code, but it will be private in a release build.