unit testing करन आप एक मुहरबंद वर्ग का नकल कैसे करते हैं?




पेपर में चीटिंग करने के तरीके (8)

सीलबंद कक्षाओं का मज़ाक उड़ाना काफी दर्द हो सकता है। मैं वर्तमान में इसे संभालने के लिए एक एडाप्टर पैटर्न का पक्ष लेता हूं, लेकिन केवल कुछ अजीब लगता है।

तो, सीलबंद कक्षाओं का नकल करने का सबसे अच्छा तरीका क्या है?

जावा उत्तर स्वागत से अधिक हैं । असल में, मुझे उम्मीद है कि जावा समुदाय इस समय से निपट रहा है और पेशकश करने का एक बड़ा सौदा है।

लेकिन यहां कुछ नेट राय हैं:


क्या इंटरफ़ेस से एक सीलबंद क्लास को कार्यान्वित करने का कोई तरीका है ... और इसके बजाय इंटरफ़ेस का नकल करें?

मुझे कुछ ऐसा लगता है कि सीलबंद कक्षाएं पहले स्थान पर गलत हैं, लेकिन यह सिर्फ मुझे है :)


अंगूठे का मेरा सामान्य नियम यह है कि जिन वस्तुओं को मुझे नकली करने की आवश्यकता है, उनमें भी एक आम इंटरफ़ेस होना चाहिए। मुझे लगता है कि यह सही डिजाइन-वार है और परीक्षणों को बहुत आसान बनाता है (और यदि आप टीडीडी करते हैं तो आमतौर पर आपको क्या मिलता है)। इसके बारे में अधिक जानकारी Google टेस्टिंग ब्लॉग नवीनतम पोस्ट में पढ़ी जा सकती है (बिंदु 9 देखें)।

इसके अलावा, मैं मुख्य रूप से पिछले 4 वर्षों में जावा में काम कर रहा हूं और मैं कह सकता हूं कि मैं एक हाथ पर गिन सकता हूं कि मैंने अंतिम (सीलबंद) कक्षा बनाई है। यहां एक और नियम यह है कि मुझे हमेशा एक वर्ग को सील करने का एक अच्छा कारण होना चाहिए, क्योंकि इसे डिफ़ॉल्ट रूप से सील करने के विपरीत।


TypeMock के साथ समस्या यह है कि यह खराब डिजाइन बहाना है। अब, मुझे पता है कि यह अक्सर किसी और का खराब डिज़ाइन होता है जो छुपा रहा है, लेकिन इसे आपकी विकास प्रक्रिया में अनुमति देने से आपके स्वयं के खराब डिज़ाइनों को अनुमति मिल सकती है।

मुझे लगता है कि यदि आप एक मॉकिंग फ्रेमवर्क का उपयोग करने जा रहे हैं, तो आपको पारंपरिक (जैसे मोक) का उपयोग करना चाहिए और अनावश्यक चीज़ के आस-पास एक अलगाव परत बनाना चाहिए, और इसके बजाय अलगाव परत का नकल करना चाहिए।


मैं लगभग हमेशा अपने कोड के भीतर बाहरी कक्षाओं पर निर्भरता से बचने से बचता हूं। इसके बजाय, मैं उनसे बात करने के लिए एडाप्टर / पुल का उपयोग करना चाहता हूं। इस तरह, मैं अपने अर्थशास्त्र से निपट रहा हूं, और अनुवाद का दर्द एक वर्ग में अलग है।

यह लंबे समय तक मेरी निर्भरताओं को स्विच करना भी आसान बनाता है।


यद्यपि यह वर्तमान में केवल बीटा रिलीज में उपलब्ध है, लेकिन मुझे लगता है कि नए फॉक्स फ्रेमवर्क ( विजुअल स्टूडियो 11 बीटा रिलीज का हिस्सा) की shim सुविधा को ध्यान में रखते हुए यह सार्थक है।

शिम प्रकार उपयोगकर्ता परिभाषित प्रतिनिधि को किसी भी .NET विधि को रोकने के लिए एक तंत्र प्रदान करते हैं। शिम प्रकार नकली जनरेटर द्वारा कोड-जेनरेट किए जाते हैं, और वे नए विधि कार्यान्वयन को निर्दिष्ट करने के लिए, प्रतिनिधियों का उपयोग करते हैं, जिन्हें हम शिम प्रकार कहते हैं। हुड के तहत, शिम प्रकार कॉलबैक का उपयोग करते हैं जिन्हें विधि एमएसआईएल निकायों में रनटाइम पर इंजेक्शन दिया गया था।

निजी तौर पर मैं ड्रॉइंग कॉन्टेक्स्ट जैसे सीलबंद ढांचे वर्गों पर विधियों का नकल करने के लिए इसका उपयोग कर रहा था।


एक सीलबंद वर्ग का नकल करना पूरी तरह से उचित है क्योंकि कई ढांचे के वर्गों को बंद कर दिया जाता है।

मेरे मामले में मैं नेट की संदेश क्यूई क्लास का नकल करने की कोशिश कर रहा हूं ताकि मैं अपने सुंदर अपवाद हैंडलिंग तर्क को टीडीडी कर सकूं।

अगर किसी के पास "गैर-अतिसंवेदनशील सदस्य पर अमान्य सेटअप" के संबंध में मोक की त्रुटि को दूर करने के बारे में विचार हैं, तो कृपया मुझे बताएं।

कोड:

    [TestMethod]
    public void Test()
    {
        Queue<Message> messages = new Queue<Message>();
        Action<Message> sendDelegate = msg => messages.Enqueue(msg);
        Func<TimeSpan, MessageQueueTransaction, Message> receiveDelegate =
            (v1, v2) =>
            {
                throw new Exception("Test Exception to simulate a failed queue read.");
            };

        MessageQueue mockQueue = QueueMonitorHelper.MockQueue(sendDelegate, receiveDelegate).Object;
    }
    public static Mock<MessageQueue> MockQueue
                (Action<Message> sendDelegate, Func<TimeSpan, MessageQueueTransaction, Message> receiveDelegate)
    {
        Mock<MessageQueue> mockQueue = new Mock<MessageQueue>(MockBehavior.Strict);

        Expression<Action<MessageQueue>> sendMock = (msmq) => msmq.Send(It.IsAny<Message>()); //message => messages.Enqueue(message);
        mockQueue.Setup(sendMock).Callback<Message>(sendDelegate);

        Expression<Func<MessageQueue, Message>> receiveMock = (msmq) => msmq.Receive(It.IsAny<TimeSpan>(), It.IsAny<MessageQueueTransaction>());
        mockQueue.Setup(receiveMock).Returns<TimeSpan, MessageQueueTransaction>(receiveDelegate);

        return mockQueue;
    }

मेरा मानना ​​है कि माइक्रोसॉफ्ट रिसर्च से Moles , आपको ऐसा करने की अनुमति देता है। मोल्स पेज से:

मॉल का उपयोग किसी भी .NET विधि को अलग करने के लिए किया जा सकता है, जिसमें सीलबंद प्रकारों में गैर वर्चुअल / स्थैतिक विधियां शामिल हैं।

अद्यतन: आगामी वीएस 11 रिलीज में "नकली" नामक एक नया ढांचा है जिसे मोल्स को बदलने के लिए डिज़ाइन किया गया है:

विजुअल स्टूडियो 11 में नकली फ्रेमवर्क अगली पीढ़ी के मोल्स और स्टब्स है, और अंत में इसे बदल देगा। मोल्स से नकली अलग है, हालांकि, मोल्स से फेक्स तक जाने के लिए आपके कोड में कुछ संशोधन की आवश्यकता होगी। इस प्रवासन के लिए एक गाइड बाद की तारीख में उपलब्ध होगा।

आवश्यकताएँ : विजुअल स्टूडियो 11 अल्टीमेट, .NET 4.5


.NET के लिए, आप TypeMock जैसे कुछ का उपयोग कर सकते हैं, जो प्रोफाइलिंग एपीआई का उपयोग करता है और आपको लगभग किसी भी चीज़ पर कॉल करने की अनुमति देता है।





mocking