2011-03-02 8 views
6

मुझे नेट 4.0 में कोड अनुबंधों के साथ एक खेल है और मुझे कुछ स्पष्ट याद आना चाहिए क्योंकि वे अपेक्षा नहीं कर रहे हैं क्योंकि मैं अपेक्षा करता हूं।यूनिट परीक्षण कोड अनुबंध

मैंने हमेशा एक सरल उपयोग किया है ... फिर .. फ़ंक्शन की शुरुआत में कोई सत्यापन करने के लिए कथन फेंक दें।

if (hours < 0 || hours > 8) 
    throw new ArgumentOutOfRangeException("hours", "Hours must be between 0 and 8"); 

मैं बस

Contract.Requires<ArgumentOutOfRangeException>(hours >= 0 && hours <= 8, "Hours must be between 0 and 8"); 

के साथ इस जगह ले ली है लेकिन यह कभी मेरी इकाई परीक्षण पर एक मुद्दा फेंक रहा है।

public static DurationUnit HoursAsDuration(int hours) 
    { 
     Contract.Requires<ArgumentOutOfRangeException>(hours >= 0 && hours <= 8, "Hours must be between 0 and 8"); 

     switch (hours) 
     { 
      case 1: 
      case 2: 
       return DurationUnit.Quarter; 
      case 3: 
      case 4: 
       return DurationUnit.Half; 
      case 5: 
      case 6: 
       return DurationUnit.ThreeQuarter; 
      case 7: 
      case 8: 
       return DurationUnit.Full; 
      default: 
       return DurationUnit.None; 
     } 
    } 

    [Test] 
    public void CanConvertToDuration() 
    { 
     Assert.AreEqual(DurationUnit.None, DateTimeUtility.HoursAsDuration(0)); 
     Assert.AreEqual(DurationUnit.Quarter, DateTimeUtility.HoursAsDuration(1)); 
     Assert.AreEqual(DurationUnit.Quarter, DateTimeUtility.HoursAsDuration(2)); 
     Assert.AreEqual(DurationUnit.Half, DateTimeUtility.HoursAsDuration(3)); 
     Assert.AreEqual(DurationUnit.Half, DateTimeUtility.HoursAsDuration(4)); 
     Assert.AreEqual(DurationUnit.ThreeQuarter, DateTimeUtility.HoursAsDuration(5)); 
     Assert.AreEqual(DurationUnit.ThreeQuarter, DateTimeUtility.HoursAsDuration(6)); 
     Assert.AreEqual(DurationUnit.Full, DateTimeUtility.HoursAsDuration(7)); 
     Assert.AreEqual(DurationUnit.Full, DateTimeUtility.HoursAsDuration(8)); 

     //Would expect this to cause an issue 
     Assert.AreEqual(DurationUnit.None, DateTimeUtility.HoursAsDuration(9)); 
    } 

परीक्षण सच रिटर्न लेकिन मैं "9" स्विच बयान में होने का मूल्य को रोकने के लिए कोड अनुबंध की उम्मीद है। क्या यह अपेक्षित व्यवहार है?

उत्तर

1

अपने कार्य के विनिर्देश, अंग्रेजी में व्यक्त करते हैं, तो यह है कि यह hours के लिए किसी भी मूल्य स्वीकार करता है और एक अपवाद फेंकता है जब hours रेंज 0..8 में नहीं है, तो अपने अनुबंध (कोड संविदा भाषा में व्यक्त) नहीं है कि 0 और 35 के बीच होने के लिए hours की आवश्यकता है। उचित अनुवाद यह है कि फ़ंक्शन को कुछ भी आवश्यकता नहीं होती है, और यह सुनिश्चित करता है कि hours गलत सीमा में था, तो एक अपवाद उठाया गया है, और यह सुनिश्चित करता है कि यदि hours था सही सीमा, उचित गणना की गई थी।

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

+0

धन्यवाद पास्कल जो कुछ चीजों को स्पष्ट करता है। मुझे विश्वास था कि कोड अनुबंध सभी पैरामीटर चेक को प्रतिस्थापित कर सकते हैं लेकिन अगर उन्हें उत्पादन निर्माण में चाहिए तो उन्हें अभी भी रहना होगा। – fluent

+0

अद्यतन: नीचे दिए गए पोर्ग ने मुझे उत्पादन निर्माण में अनुबंध सक्षम करने के लिए परियोजना सेटिंग्स को संपादित करने के साथ सही दिशा में इंगित किया है। – fluent

-1

मुझे लगता है कि आपको अपने घंटों के पैरामीटर पर परीक्षणों को स्वैप करने की आवश्यकता है।

आपको पारित नियम को परिभाषित करना होगा।

इसलिए मुझे लगता है कि यह आपके लिए काम करेगा ...

Contract.Requires<ArgumentOutOfRangeException>(hours < 0 && hours > 8, "Hours must be between 0 and 8"); 
+0

धन्यवाद, आपने मेरी पोस्ट में एक त्रुटि देखी जो थोड़ा भ्रामक था। मूल अगर .. तो .. फेंक गलत था जिसे मैंने अभी सही किया है। हालांकि समस्या अभी भी मौजूद है। – fluent

+4

-1: यह कोई समझ नहीं आता है। आप अनिवार्य रूप से बताते हैं कि आप _require_ 'घंटे' शून्य से कम और एक ही समय में 8 से अधिक होने के लिए हैं। – Virtlink

0

ठीक है, मैं अब कोड को सक्षम करने से उम्मीद त्रुटि फेंक दृश्य स्टूडियो में परियोजना गुण के भीतर विकल्प "रनटाइम अनुबंध जाँच हो रही है प्रदर्शन करना" ।

क्या इसका मतलब यह है कि जब कोड अनुबंधों को प्रभावी ढंग से अनदेखा किया जाता है तो उत्पादन के लिए जारी किया जाता है?

मैं obviosuly गलतफहमी कर रहा हूँ कि कैसे कोड अनुबंधों का उपयोग किया जाना चाहिए ताकि अगर कोई मुझे एक सर्वोत्तम अभ्यास लेख की दिशा में इंगित कर सकता है तो मैं आभारी रहूंगा।

MSDN पेज कहता है:

"अनुबंध कक्षा में सबसे तरीकों सशर्त संकलित किए जाते हैं, अर्थात, संकलक इन तरीकों के लिए कॉल का उत्सर्जन करता है केवल जब आप एक विशेष प्रतीक परिभाषित करते हैं, पूर्ण अनुबंध, #define का उपयोग करके निर्देश। अनुबंध पूर्ण आपको #ifdef निर्देशों का उपयोग किए बिना अपने कोड में अनुबंध लिखने देता है; आप अलग-अलग निर्माण, कुछ अनुबंधों के साथ, और कुछ बिना उत्पादन कर सकते हैं। "

क्या इसका मतलब यह है कि मैं अभी भी उपयोग करने के बेहतर होगा .. फिर .. फेंक .. किसी भी सार्वजनिक सामना के लिए? पैरामीटर सत्यापन जांच वास्तव में डेटा भ्रष्टाचार पर कटौती करने में मदद करती है क्योंकि यह जितनी जल्दी हो सके विफलता के बिंदु को झेलती है।

+0

मैं आपके उत्तर में सभी प्रश्नों के लिए "हाँ" कहूंगा, और मैं थोड़ी सी विस्तार करूँगा, लेकिन स्टैक ओवरव्लो टिप्पणियां थोड़ी सीमित हैं, इसलिए मैंने इसके बजाय एक और जवाब लिखा। –

+1

rggardner: प्रोजेक्ट गुणों में कई विकल्प हैं :) आप रिलीज बिल्ड के लिए रनटाइम प्रवर्तन सक्षम कर सकते हैं या अपनी इच्छानुसार अक्षम कर सकते हैं। यह इस बात पर निर्भर करता है कि आप अनुबंधों के साथ क्या करना चाहते हैं। आप इसे केवल सार्वजनिक-सामना करने वाली विधियों आदि पर सक्षम कर सकते हैं, – porges

+0

धन्यवाद पोर्गेस, जानना बहुत उपयोगी है। मुझे बस इतना करना है कि मेरी बिल्ड फाइलों में सही सेटिंग्स काम करें। – fluent