2012-03-02 9 views
10

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

मैं एन # एनआईएनआईटी के साथ सी # का उपयोग कर रहा हूं।

[Test] 
public void ShouldAllowInstanceToBeCreatedWhenXMLFileIsPresent() 
{ 
    if (File.Exists(SettingsReader.XML_SETTINGS_PATH)) 
    { 
     SettingsReader settingsReader = new SettingsReader(); 
     Assert.AreNotEqual(null, settingsReader); 
    } 
} 

[Test] 
[ExpectedException("Telekanzlei.Clientmanager.XMLDataLayer.XMLFileNotFoundException")] 
public void ShouldThrowExceptionWhenXMLFileIsNotPresent() 
{ 
    if (!File.Exists(SettingsReader.XML_SETTINGS_PATH)) 
    { 
     SettingsReader settingsReader = new SettingsReader(); 
    } 
     else 
      throw new XMLFileNotFoundException(); 
    } 

मैं अगर परीक्षा में फ़ाइल के अस्तित्व की जाँच जाने के लिए एक उचित तरीके से है, इसलिए उन परीक्षण पर कोई सुझाव भी स्वागत कर रहे हैं यकीन नहीं है: अब तक मैं दो परीक्षण मिल गया है। लेकिन मेरा सवाल यह है कि निम्नलिखित परीक्षणों के साथ कैसे आगे बढ़ना है। स्पष्ट रूप से सभी निम्न परीक्षण विफल होने जा रहे हैं, यदि XML-file मौजूद नहीं है।

तो क्या मुझे लगता है कि एक्सएमएल फ़ाइल मौजूद है, जबकि ध्यान में रखते हुए, एक असफल परीक्षण का मतलब यह हो सकता है कि यह नहीं है? यह मेरे लिए सही प्रतीत नहीं होगा।

क्या इस तरह की समस्या को संभालने के लिए कोई सामान्य पैटर्न है? किसी भी मदद

संपादन के लिए

Thx:, दूसरे टेस्ट दुबारा लिखा है, तो फ़ाइल वास्तव में मौजूद था के रूप में यह असफल रहा था ...

EDIT2: मई यह आपको बताने के लिए मदद कर रहा है, क्या वास्तव में SettingsReader कर देता है। अब तक यह इस तरह दिखता है:

public class SettingsReader 
{ 
    public static readonly string XML_SETTINGS_PATH = "C:\\Telekanzlei\\Clientmanager_2.0\\Settings.xml"; 

    public XElement RootXElement { get; private set; } 

    public SettingsReader() 
    { 
     if (!File.Exists(XML_SETTINGS_PATH)) 
      throw new XMLFileNotFoundException(); 
     using (var fs = File.OpenRead(XML_SETTINGS_PATH)) 
     { 
      RootXElement = XElement.Load(fs); 
     } 
    } 


} 

मुझे यकीन है कि नहीं कर रहा हूँ, लेकिन मुझे लगता है कि एक StreamReader यहां जाने का रास्ता नहीं होगा, यह होगा?

+3

क्या सेटिंग्स रीडर निर्भरता इंजेक्शन का उपयोग करने के लिए डिज़ाइन किया गया है? डीआई और मॉकिंग के लिए एक अच्छा मामला लगता है। –

+1

एमएसटीएस्ट के लिए [परिनियोजन इटिम] है। शायद NNnit ऐसा कुछ है? –

उत्तर

14

समस्या आपके यूनिट परीक्षणों के साथ नहीं है बल्कि कक्षा के डिजाइन के साथ है। मैं कक्षा को दोबारा सुधारने का सुझाव दूंगा ताकि यह फ़ाइल नहीं खोल सके बल्कि इसके बजाय स्ट्रीम पर काम करता है। फिर आपके यूनिट परीक्षण मेमोरी स्ट्रीम के लिए बस एक फ़ाइल स्ट्रीम को प्रतिस्थापित कर सकते हैं - सिंपल! :)

public class SettingsReader() 
{ 
    public SettingsReader(System.IO.StreamReader reader) 
    { 
     // read contents of stream... 
    } 
} 

// In production code: 
new SettingsReader(new StreamReader(File.Open("settings.xml"))); 

// In unit test: 
new SettingsReader(new StringReader("<settings>dummy settings</settings>")); 

याद रखें, फ़ाइल खोलना और सेटिंग्स डेटा पार्सिंग दो बहुत ही अलग चिंताएं हैं।

+0

मुझे अभी एहसास हुआ कि XElement.Load-method पैरामीटर के रूप में स्ट्रीम ले रहा है। मैं अभी तक .NET से परिचित नहीं हूँ। लेकिन आपका सुझाव एक अच्छा दृष्टिकोण की तरह लगता है। तो मैं विभाजित करने जा रहा हूं कि चलिए एक सेटिंगस्ट्रीमप्रोवाइडर-क्लास और एक सेटिंग पार्सर-क्लास कहें और पार्सर के लिए निर्भरता इंजेक्शन का उपयोग करें? – Tobi

+0

सेटिंग स्ट्रीम प्रदाता क्लास का केवल एक सादा स्ट्रीम पर क्या मूल्य होगा? मुझे लगता है कि यह एक व्यर्थ अमूर्त होगा - KISS :) – MattDavey

+0

प्वाइंट लिया ^^ बात यह है कि मैं अपने प्रोजेक्ट में एकाधिक अवसरों पर सेटिंग्स रीडर का उपयोग कर रहा हूं, लेकिन हमेशा एक ही एक्सएमएल फ़ाइल के साथ। जब भी मैं इसका इस्तेमाल करता हूं, मैं इसे "मैन्युअल रूप से" एक नई स्ट्रीम बनाने के लिए बहुत पसंद नहीं करता। यही कारण है कि मैं सेटिंग रीडर-क्लास में स्ट्रीम-ओपनिंग को पहले स्थान पर संभालना चाहता था ... – Tobi

5

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

3

पुन: लिखने के कोड पर विचार करें ताकि निर्भरता को पारित किया जा सके या किसी भी तरह से उस कोड के लिए स्टब किया जा सके जिसे आप यूनिट-टेस्ट करना चाहते हैं।

आईई। सेटिंग्स रीडर कन्स्ट्रक्टर को "IMySettingsFileProvider" उदाहरण जैसे कुछ पास करें जहां IMySettingsFileProvider.SettingsXml कुछ सेटिंग स्ट्रीम देता है। डिस्क पर मौजूद होने की आवश्यकता के बजाय परीक्षण के लिए आप IMySettingsFileProvider इंटरफ़ेस का नकल कर सकते हैं।

+1

क्या यह "ओवरकिल" का थोड़ा सा नहीं होगा? एक्सएमएल-फाइल का उपयोग केवल इस एकल वर्ग द्वारा किया जाता है। केवल फाइल लोड करने के लिए इंटरफ़ेस + कक्षा बनाना? – Tobi

+1

सहमत हुए। मुझे समझ में नहीं आता है कि क्यों लोग मजाक कर इतना जटिलता जोड़ते हैं क्योंकि यह करने का "शुद्ध" तरीका है। आप उस कोड को लीवरेज करने से बेहतर हैं जिसने इसे बनाने के लिए फ़ाइल बनाई है/इसे एक अस्थायी स्थान पर कॉपी करें, इसका उपयोग करें, फिर इसे हटाएं। – tsells

+0

हां यह हो सकता है। यही कारण है कि मैंने "विचार करें ..." लिखने की कोशिश की - यदि यह आपके मामले के लिए ऐसा करने के बजाय काम करता है, यदि नहीं - तो कुछ और करें (जिसे पहले से ही पहले के उत्तर के रूप में सुझाव दिया गया था)। –

1

एक विकल्प यह परीक्षण स्थिरता के शीर्ष पर रखना है। तब परीक्षण केवल तभी मान्य होगा जब फ़ाइल मौजूद हो।

[SetUp] 
public void Setup() 
{ 
    Assume.That(File.Exists(SettingsReader.XML_SETTINGS_PATH)); 
} 
संबंधित मुद्दे