2008-09-20 3 views
103

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

+2

संभव [सी # "आंतरिक" पहुंच मोडी का डुप्लिकेट इकाई परीक्षण करते समय भयंकर] [http://stackoverflow.com/questions/358196/c-sharp-internal-access-modifier-when-doing-unit-testing) –

उत्तर

160

यदि आप .NET का उपयोग कर रहे हैं, तो InternalsVisibleTo असेंबली विशेषता आपको "मित्र" असेंबली बनाने की अनुमति देती है। ये विशिष्ट दृढ़ता से नामांकित असेंबली हैं जिन्हें आंतरिक वर्गों और अन्य असेंबली के सदस्यों तक पहुंचने की अनुमति है।

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

+0

का उपयोग नहीं कर सकते/नहीं करना चाहिए! यह निश्चित रूप से स्वीकृत उत्तर होना चाहिए। – fresskoma

+14

मैं विशेषता के चारों ओर एक #if DEBUG डालने का सुझाव देना चाहता हूं, और फिर डीबग में इकाई परीक्षण करना चाहता हूं। इस तरह आप सुनिश्चित होंगे कि विशेषता रिलीज कोड पर सेट नहीं है। –

+0

यह सिर्फ एक विचार है, मैं नहीं जानता कि है .... कैसे के बारे में: डीबग #else IniReader आंतरिक वर्ग IniReader सार्वजनिक वर्ग #if #endif शायद अनुशंसित नहीं? क्यूं कर? – jmelhus

-2

कक्षाएं सार्वजनिक और मुहरबंद दोनों हो सकती हैं।

लेकिन, ऐसा मत करो।

आप आंतरिक कक्षाओं को प्रतिबिंबित करने के लिए एक उपकरण बना सकते हैं, और एक नई कक्षा को छोड़ सकते हैं जो प्रतिबिंब के माध्यम से सबकुछ एक्सेस करता है। एमएसटीएस्ट ऐसा करता है।

संपादित करें: मेरा मतलब है, यदि आप अपनी मूल असेंबली में कई परीक्षण सामग्री शामिल नहीं करना चाहते हैं; यह भी काम करता है अगर सदस्य निजी हैं।

+1

रुको, क्या? आप कह रहे हैं कि 'सार्वजनिक मुहरबंद वर्ग' न बनाएं? उस मणि के लिए आपका तर्क क्या है? – crush

5

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

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

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

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

+0

कार्यान्वयन विवरण का उपयोग एक व्यापक परीक्षण के हिस्से के रूप में किया जाना चाहिए। निजी चर पर नज़र डालें ... परीक्षण अपेक्षित व्यवहार। यदि परीक्षण सही है .. सभी आंतरिक नलसाजी और तारों का परीक्षण इसके हिस्से के रूप में किया जाना चाहिए। वोट दिया – Gishu

+61

मैं इस बात से सहमत नहीं हूं क्योंकि ये कक्षाएं डीएलएल के अंदर अन्य कक्षाओं में "सार्वजनिक" हैं और कक्षा की कार्यक्षमता का परीक्षण – leora

+22

पर भी किया जाना चाहिए, मैं भी सहमत नहीं हूं। इकाइयां इकाइयां हैं और उन्हें अलगाव में परीक्षण किया जाना चाहिए। – Sentinel

3

प्रलेखन प्रयोजनों

वैकल्पिक रूप से आप सामान्य प्रकार के लिए Type.GetType विधि

उदाहरण

//IServiceWrapper is public class which is 
//the same assembly with the internal class 
var asm = typeof(IServiceWrapper).Assembly; 
//Namespace.ServiceWrapper is internal 
var type = asm.GetType("Namespace.ServiceWrapper"); 
return (IServiceWrapper<T>)Activator 
    .CreateInstance(type, new object[1] { /*constructor parameter*/ }); 

का उपयोग करके आंतरिक वर्ग का दृष्टांत कर सकते हैं अलग-अलग प्रक्रिया के रूप में bellow हैं के लिए:

var asm = typeof(IServiceWrapper).Assembly; 
//note the name Namespace.ServiceWrapper`1 
//this is for calling Namespace.ServiceWrapper<> 
var type = asm.GetType("Namespace.ServiceWrapper`1"); 
var genType = type.MakeGenericType(new Type[1] { typeof(T) }); 
return (IServiceWrapper<T>)Activator 
    .CreateInstance(genType, new object[1] { /*constructor parameter*/}); 
संबंधित मुद्दे