2014-10-04 7 views
5

मेरे पास कक्षा A है कि मैं एक विधि परीक्षण कर रहा हूं जिस पर कक्षा B पैरामीटर के रूप में लेता है। कक्षा B वह है जो मैं नकल करने की कोशिश कर रहा हूं, और यह एक अमूर्त वर्ग है। कक्षा नीचे जैसा ही है।एमओक का उपयोग करके एक आंतरिक सार विधि युक्त एक अमूर्त वर्ग का नकल कैसे करते हैं?

public abstract class B 
{ 
    internal abstract void DoSomething(); 
} 

मेरा यूनिट परीक्षण कैसा दिखता है।

[TestMethod] 
public void ClassA_Add_TestSomething() 
{ 
    var classA = new A(); 
    var mock = new Mock<B>(); 

    classA.Add(mock.Object); 

    // Assertion 
} 

मुझे निम्न अपवाद प्राप्त होता है।
System.ArgumentException:: प्रकार उपहास करने के लिए एक अंतरफलक या एक सार या गैर सील वर्ग होना चाहिए

टेस्ट विधि TestSomething अपवाद फेंक दिया। ---> System.TypeLoadException: 'DSomething' विधि 'Castle.Proxies.BProxy' में 'असेंबली' DynamicProxyGenAssembly2, संस्करण = 0.0.0.0, संस्कृति = तटस्थ, PublicKeyToken = null 'में कोई कार्यान्वयन नहीं है।

मैं अमूर्त के बजाय विधि वर्चुअल बनाकर इसे प्राप्त कर सकता हूं, लेकिन ऐसा नहीं है कि मैं एपीआई डिज़ाइन के साथ पूरा करना चाहता हूं। मैंने इसका लाभ उठाने के लिए mock.Setup(m => m.DoSomething()) के माध्यम से इसे कार्यान्वित करने का भी प्रयास किया है। क्या यह मोक के साथ संभव है, या क्या मुझे अमूर्त कक्षा बी से प्राप्त एक ठोस परीक्षण वर्ग बनाना होगा? मैं कंक्रीट प्रकार बनाने से बचना चाहता था, जो मॉकिंग या स्टबिंग फ्रेमवर्क का उपयोग करने के कुछ उद्देश्य को हरा देता है, या क्या मैं यहां गुमराह हूं?

संपादित मैं ने पाया है कि अगर मैं विधि public abstract कर इस मुद्दे को नहीं होती है। तो मुझे लगता है कि वास्तविक सवाल यह है कि यदि आंतरिक VisibleTo और Moq का उपयोग करते समय आंतरिक विधि के साथ यह भी संभव है।

+0

आप mock.Setup का उपयोग क्यों नहीं कर सकते? – brz

+0

मुझे अपवाद प्राप्त होता है कि मैं सेटअप का उपयोग करता हूं या नहीं। मेरे यूनिट टेस्ट में, मुझे परवाह नहीं है कि 'बी डूसमिंग' का अनुकरण है या नहीं, हालांकि मुझे समझ में आता है कि इसकी आवश्यकता क्यों होगी।यह संभव है कि मैं 'सेटअप' का सही ढंग से उपयोग नहीं कर रहा हूं, लेकिन मैंने जो कोशिश की थी वह बहुत ही बुनियादी 'mock.Setup (m => m.DoSomething()) है। कॉलबैक (() => {}); ' –

+4

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

उत्तर

3

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

5

मोक अपने मैक्स को लागू करने के लिए Castle Dynamic Proxy पर निर्भर करता है। रनटाइम पर, एक नई असेंबली बनाई जाती है और आपके ऐपडोमेन में मोक द्वारा नामित किया जाता है (नाम डायनामिकप्रॉक्सिजेनएस्पर स्पिल 2 जो अपवाद संदेश में दिखाई देता है)।

मुद्दा यह है कि इस विधानसभा आंतरिक वर्गों और अपने खुद के कोड के सदस्यों तक नहीं पहुँच सकता है, क्योंकि वे विधानसभा जहाँ आप उन्हें घोषित बाहर से दिखाई नहीं कर रहे हैं।

[InternalsVisibleTo("DynamicProxyGenAssembly2")] 

लेकिन याद रखें कि यह समाधान एक कार्यान्वयन विस्तार पर निर्भर करता है, और भविष्य में काम करना बंद कर सकता है:

एक वैकल्पिक हलInternalsVisibleToAttribute के साथ अपने विधानसभा चिह्नित करने और गतिशील रूप से उत्पन्न विधानसभा का नाम निर्दिष्ट करने के लिए है संस्करणों।

+2

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

+1

@ डेविड एंडरसन-डीसीओएम का उल्लेख है, यह समाधान इस मामले में काम नहीं करता है। मैं अपने परीक्षण में इसकी पुष्टि कर सकता हूं। –

संबंधित मुद्दे