2012-01-07 14 views
6

मैं यूनिट टेस्टेबल कोड बनाना चाहता हूं जो .NET System.IO कक्षाओं को कॉल करता है, इसलिए मैं वास्तव में फाइल सिस्टम के आधार पर यूनिट परीक्षण कर सकता हूं। मैं बीसीएल कक्षाओं के चारों ओर लपेटने के लिए SystemWrapper कक्षाओं का उपयोग कर रहा हूं।.NET IO कक्षाओं का उपयोग करके टेस्टेबल कोड कैसे बनाएं?

मैं एक साधारण उदाहरण प्राप्त करने की कोशिश कर रहा हूं यह देखने के लिए कि कोई फ़ाइल मौजूद है या नहीं।

मेरी समस्या यह है कि कक्षा में निर्भरता इंजेक्शन करना काम नहीं करता है क्योंकि निर्भरता को तत्काल (StructureMap के माध्यम से) को यह जानने की आवश्यकता है कि किस रचनाकार पैरामीटर को पास करना है, जो उस समय उपलब्ध नहीं होगा, कोई डिफ़ॉल्ट कन्स्ट्रक्टर नहीं।

नमूना कोड:

// don't want to create dependency here like so 
//IFileInfoWrap fileInfoWrap = new FileInfoWrap(filename); 

// using service locator (anti-pattern?!) since it can't be 
// injected in this class 
var fileInfoWrap = ObjectFactory.GetInstance<IFileInfoWrap>(
    new ExplicitArguments(new Dictionary<string, object> 
    { 
     {"fileName", filename} 
    })); 

Console.WriteLine("File exists? {0}", fileInfoWrap.Exists); 

क्या मुझे पसंद नहीं है कि निर्भरता इंजेक्शन नहीं है, ObjectFactory यहाँ नहीं होना चाहिए (लेकिन मैं इस बनाने का कोई दूसरा रास्ता नहीं देखें)। स्पष्टीकरणअधिकरण इसे गन्दा बनाता है और तर्क-नाम एक जादू-स्ट्रिंग है।

ObjectFactory.Initialize(x => 
{ 
    x.Scan(scan => 
    { 
     scan.AssembliesFromPath("."); 
     scan.RegisterConcreteTypesAgainstTheFirstInterface(); 
     scan.WithDefaultConventions(); 
    }); 

    // use the correct constructor (string instead of FileInfo) 
    x.SelectConstructor(() => new FileInfoWrap(null as string)); 

    // setting the value of the constructor 
    x.For<IFileInfoWrap>() 
     .Use<FileInfoWrap>() 
     .Ctor<string>("fileName") 
     .Is(@"."); 
}); 
:

मुझे इस StructureMap config वर्ग काम करने के लिए प्राप्त करने के लिए के लिए पता करने के लिए explict निर्माता जो मैं (मैं सिर्फ StructureMap के साथ शुरू किया तो यह इसे सेट अप करने के लिए सही तरीके से नहीं किया जा सकता है) का उपयोग करना चाहते जरूरत

क्या किसी को सिस्टम.आईओ कक्षाओं के खिलाफ टेस्टेबल कोड बनाने के लिए बेहतर समाधान मिला है? मुझे पता है कि समस्या का हिस्सा System.IO कक्षाओं के डिज़ाइन में है।

+3

SystemWrapper ज्यादातर अत्यंत टपकाया कपोल-कल्पना में शामिल है। स्ट्रीम, टेक्स्टवाइटर, टेक्स्ट रीडर इत्यादि के खिलाफ IO मॉडल IO के लिए यह बहुत आसान और आसान होगा। ये कक्षाएं पहले ही अमूर्त हैं, पूरी तरह से SystemWrapper की आवश्यकता को हटा रही हैं। –

+0

स्ट्रीम के लिए एक और वोट –

+0

सिस्टमवापर के साथ मेरे निष्कर्ष यह है कि यह इंटरफेस के साथ एक अच्छा रैपर प्रतीत होता है, हालांकि मूल वर्गों के काम के कारण यह अभी भी एक मृत अंत है। उदाहरण के लिए FileInfo ऑब्जेक्ट्स की एक सरणी लौटने से ठीक से मैक नहीं किया जा सकता है। अपने स्वयं के अधिक सरलीकृत रैपर को रोल करना जो मौजूदा वर्गों की नकल करने की ज़रूरत नहीं है, जबकि अधिक काम होने से एक व्यावहारिक समाधान आईएमएचओ होता है। –

उत्तर

5

एक दृष्टिकोण जिसने मैंने सफलतापूर्वक उपयोग किया है, System.IO और एफसीएल के अन्य हिस्सों में पाए गए प्रकारों के लिए अपने स्वयं के प्रॉक्सी प्रकारों को रोल करना है। जैसे मैं System.IO.File पर निर्भरता लेना चाहता हूं। मैं System.IO.Proxies नामक एक लाइब्रेरी बनाता हूं और एक ठोस प्रकार File और इंटरफ़ेस IFile जोड़ता हूं। इंटरफ़ेस IFile उन सभी सदस्यों के समतुल्य सदस्यों को दिखाता है जिन्हें मुझे System.IO.File से आवश्यकता होती है और ठोस प्रकार उन सदस्यों को System.IO.File पर अग्रेषण विधि कॉल के अलावा कुछ भी नहीं कर रहा है। System.IO.Proxies इकाई परीक्षण और कोड कवरेज से बाहर रखा गया है। मेरी उपभोग करने वाली असेंबली में, मैं केवल System.IO.Proxies पर निर्भरता लेता हूं और, विशेष रूप से, मैं केवल IFile पर निर्भरता लेता हूं। इस तरह मैं इस निर्भरता को आसानी से नकल कर सकता हूं और मेरी उपभोक्ता असेंबली के लिए 100% कोड कवरेज प्राप्त कर सकता हूं।

(ध्यान दें कि यह मेरा more general answer एक पिछले प्रश्न के अनुरूप संस्करण है।)

+0

हां, यही तरीका है कि मैं भी समाप्त हुआ। कोई कॉल को निर्दिष्ट कर सकता है उदा। एक अलग वर्ग के लिए System.IO.FileInfo। अपनी खुद की प्रॉक्सी को रोल करने के लिए प्रत्येक वर्ग के लिए प्रॉक्सी बनाने की आवश्यकता होती है जो काफी कुछ काम हो सकती है, बेशक यह बीसीएल कक्षा से आवश्यक कार्यक्षमता के साथ बढ़ सकता है। जब अन्य प्रकार (FileInfo) लौटाए जाते हैं, तो सभी आवश्यक विशेषताओं को प्रॉक्सी (नाम, पूर्ण नाम, लंबाई) में बनाया जाना चाहिए। कोई सोचता है कि यह समस्या पहले से ही सभी के लिए प्रॉक्सीइंग से बचने के लिए 'हल हो जाएगी'। –

+0

एक ही दृष्टिकोण को सफलतापूर्वक इस्तेमाल किया। आम तौर पर आपको _File_ जैसी कक्षा के सभी तरीकों/गुणों/घटनाओं की आवश्यकता नहीं होती है। और मुट्ठी भर के लिए आपको ऐसे रैपर लिखना वाकई आसान है। –

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