2012-02-21 16 views
5

मैं इकाई में एक निजी समारोह का परीक्षण करने की कोशिश कर रहा हूं। यह निजी फ़ंक्शन myClass का संग्रह देता है, जो एक आंतरिक वर्ग है।आंतरिक दृश्यमान लगता है

मैंने असेंबली विशेषता InternalsVisibleTo का उपयोग किया है, ताकि myClass टाइप मेरे टेस्ट प्रोजेक्ट में जाना जा सके।

namespace MyProject 
{ 
    public class Class1 
    { 
     private List<myClass> myFunction() 
     { 
      return new List<myClass>(); 
     } 

     internal class myClass 
     { 
      public int MyProperty { get; set; } 
     } 
    } 
} 

[TestMethod()] 
[DeploymentItem("MyProject.dll")] 
public void myFunctionTest() 
{ 
    Class1_Accessor target = new Class1_Accessor(); 
    List<Class1_Accessor.myClass> expected = null; 
    List<Class1_Accessor.myClass> actual; 
    actual = target.myFunction(); 
    Assert.AreEqual(expected, actual); 
    Assert.Inconclusive("Verify the correctness of this test method."); 
} 

और मेरी विधानसभा की जानकारी फ़ाइल में:

[assembly: InternalsVisibleTo("MyProject.Test")] 

तो क्यों करता है दृश्य स्टूडियो myClass के बाद से Class1_Accessor.myClass को सूची के प्रकार सेट जाना जाता है

यहाँ कोड मैं परीक्षण करना चाहते हैं मेरे परीक्षण परियोजना के लिए?

इसके कारण मुझे रनटाइम त्रुटि मिलती है (टाइप Class1_Accessor.myClass टाइप करने के लिए परिवर्तित नहीं कर सकता)।

क्योंकि myfunction निजी है, VisualStudio निम्नलिखित कोड (जो इसमें से अधिकांश के लिए ठीक है)

[Shadowing("MyProject.Class1")] 
public class Class1_Accessor : BaseShadow 
{ 
    protected static PrivateType m_privateType; 

    [Shadowing("[email protected]")] 
    public Class1_Accessor(); 
    public Class1_Accessor(PrivateObject value); 

    public static PrivateType ShadowedType { get; } 

    public static Class1_Accessor AttachShadow(object value); 
    [Shadowing("[email protected]")] 
    public List<Class1_Accessor.myClass> myFunction(); 

    [Shadowing("MyProject.Class1+myClass")] 
    public class myClass : BaseShadow 
    { 
     protected static PrivateType m_privateType; 

     [Shadowing("[email protected]")] 
     public myClass(); 
     public myClass(PrivateObject value); 

     [Shadowing("MyProperty")] 
     public int MyProperty { get; set; } 
     public static PrivateType ShadowedType { get; } 

     public static Class1_Accessor.myClass AttachShadow(object value); 
    } 
} 

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

+0

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

+0

धन्यवाद , मैंने टैग जोड़ा है। निजी सदस्यों का परीक्षण करना या नहीं, एक अलग विषय है (हालांकि आप सही हैं)। फिर भी, मैं अभी भी उस समारोह का परीक्षण करना चाहता हूं। – Sam

+0

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

उत्तर

0

आंतरिक VisibleTo निजी सदस्यों को मित्र असेंबली के लिए दृश्यमान नहीं बनाता है। यह सदस्यों के रूप में चिह्नित सदस्यों/प्रकारों पर काम करता है। दस्तावेज़ here देखें।

अद्यतन

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

+1

कृपया मेरा प्रश्न फिर से पढ़ें। टाइप MyClass आईएस आंतरिक, निजी नहीं है। यह केवल वह तरीका है जिसे मैं परीक्षण करना चाहता हूं वह निजी है। – Sam

+2

आपके कोड में, मेरा कार्य निजी है। – Fernando

+0

हां, मेरा कार्य निजी है इसलिए यह सामान्य है कि विजुअलस्टूडियो इसके लिए एक एक्सेसर बनाता है। हालांकि, MyClass आंतरिक है (और असेंबली फ़ाइल में एक मित्र के रूप में चिह्नित) इसलिए मुझे समझ में नहीं आता कि VisualStudio इसके लिए एक एक्सेसर क्यों बनाता है। – Sam

4

चेक किया गया है प्रकार myClass परिवर्तित नहीं कर सकते Class1_Accessor.myClass टाइप करने के लिए बनाने के

कहते हैं सब कुछ हम जानते हैं की जरूरत है: बस - आप दो अलग अलग परिभाषा है myClass का। प्रकार असेंबली द्वारा scoped हैं; [InternalsVisibleTo(...)] इसे सुलभ बनाता है, लेकिन उससे परे: सामान्य रूप से व्यवसाय।

लगाएं कि/जहां एक दूसरे myClass, और में से एक है:

  • को स्पष्ट (नाम स्थान योग्य आदि)
  • का नाम बदलने के लिए उनमें से एक
  • उनमें से एक को दूर अगर वे एक ही मतलब है बात है, और गलत तरीके से दोहराया गया है

यह होने के रूप में बिल्कुल वैसा ही है:

namespace A { class Foo {} } 
namespace B { class Foo {} } 

जो Foo नामक दो पूरी तरह से असंबंधित कक्षाएं हैं, और उनके बीच कास्टिंग विफल हो जाएगी।

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