16

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

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

+2

डुप्लिकेट: http://stackoverflow.com/questions/1465849/using-ioc-for-unittesting –

+0

धन्यवाद, मैं नहीं कर सका इसे कहीं भी ढूंढें;) –

उत्तर

20

आपको इकाई परीक्षणों में डी कंटेनर की आवश्यकता नहीं है क्योंकि निर्भरता Rhino Mocks या Moq जैसे ढांचे के साथ उत्पन्न नकली वस्तुओं के माध्यम से प्रदान की जाती है। तो उदाहरण के लिए जब आप किसी ऐसे वर्ग का परीक्षण कर रहे हैं जिस पर कुछ इंटरफेस पर निर्भरता है तो यह निर्भरता आमतौर पर कन्स्ट्रक्टर इंजेक्शन के माध्यम से प्रदान की जाती है।

public class SomeClassToTest 
{ 
    private readonly ISomeDependentObject _dep; 
    public SomeClassToTest(ISomeDependentObject dep) 
    { 
     _dep = dep; 
    } 

    public int SomeMethodToTest() 
    { 
     return _dep.Method1() + _dep.Method2(); 
    } 
} 

अपने आवेदन में आप जबकि एक इकाई परीक्षण में आप एक नकली वस्तु बनाने क्योंकि आप केवल परीक्षण करना चाहते हैं निर्माता जो अपने आप अन्य वस्तुओं पर निर्भरता हो सकता था में ISomeDependentObject के कुछ वास्तविक कार्यान्वयन पारित करने के लिए एक डि ढांचे का उपयोग करेगा अलगाव में यह वर्ग। राइनो मोक्स के साथ उदाहरण:

[TestMethod] 
public void SomeClassToTest_SomeMethodToTest() 
{ 
    // arrange 
    var depStub = MockRepository.CreateStub<ISomeDependentObject>(); 
    var sut = new SomeClassToTest(depStub); 
    depStub.Stub(x => x.Method1()).Return(1); 
    depStub.Stub(x => x.Method2()).Return(2); 

    // act 
    var actual = sut.SomeMethodToTest(); 

    // assert 
    Assert.AreEqual(3, actual); 
} 
+0

उचित लगता है। आखिरकार, यह वही है जो मैं कर रहा हूं। मुझे यकीन नहीं था कि यह एक अच्छा अभ्यास है, खासकर जब बहुत निर्भरताएं होती हैं और मुझे उन्हें मैन्युअल रूप से नकल करना पड़ता है। –

+0

मेरे उत्तर थॉमस में बात की गई ऑटोमॉकिंग पर एक नज़र डालें, यह वास्तव में कई निर्भरताओं के साथ परीक्षण कक्षाओं को सरल बनाता है। :-) –

2

मैंने अभी एक बहुत ही समान शैली और आकार ऐप लिखा है। मैं यूनिट परीक्षणों में कोई निर्भरता इंजेक्शन नहीं डालूंगा क्योंकि यह आवश्यक होने के लिए पर्याप्त जटिल नहीं है। आपको अपने मॉक्स (RhinoMocks/Moq) बनाने के लिए एक मॉकिंग फ्रेमवर्क का उपयोग करना चाहिए।

Moq में Automocking या राइनोमॉक्स में Auto Mock Container में आपके मैक्स को और अधिक सरल बनाना आसान होगा।

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

+0

हां, लेकिन ऑटो मॉक कंटेनर भी एक आईओसी कंटेनर नहीं है? ;) यह निर्भर करता है कि यह निर्भरताओं को हल करने के संबंध में अधिक आराम से है: यह "उचित" विंडसर कंटेनर जैसे अनसुलझे सामानों के अपवाद फेंकने के बिना सेवाओं के डिफ़ॉल्ट नकली कार्यान्वयन उत्पन्न करेगा। –

+1

... और सबसे महत्वपूर्ण बात यह है कि इसे बनाने के लिए केवल दो लाइनें लगती हैं! तथ्य यह है कि आपको किसी भी निर्भरता को पंजीकृत करने की आवश्यकता नहीं है, इसका मतलब है कि यह एक नियमित आईओसी से आसान है। यद्यपि ऑटोमॉकिंग का उपयोग करने का एक अन्य कारण परीक्षण के निर्माता के तहत ऑब्जेक्ट को कॉल को दूर करना है। इसलिए, अगर हस्ताक्षर में परिवर्तन होता है तो आपको अपने परीक्षण वर्गों को कम भंगुर बनाने के लिए कई परीक्षणों को बदलने की ज़रूरत नहीं है। :-) –

3

मैं लगभग 400 यूनिट परीक्षणों के साथ एक एएसपी.नेट एमवीसी परियोजना पर काम कर रहा हूं। मैं परीक्षण के लिए निर्भरता इंजेक्शन और एमबीयूनीट के लिए निनजेक्ट का उपयोग कर रहा हूं।

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

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

मैं कुछ परीक्षणों में ऑब्जेक्ट्स (फिकिंग के विपरीत) का मज़ाक उड़ा रहा हूं, लेकिन मुझे पता चला कि डाटा रिपॉजिटरीज़ को कम काम और अधिक सटीक परीक्षणों में फोकस करना पड़ता है।

उदाहरण के लिए, यह जांचना अधिक कठिन होगा कि परीक्षण के तहत विधि मैं रिपोजिटरी नकली का उपयोग करते समय रिपोजिटरी नकली का उपयोग करते समय उन्हें ठीक से रिपॉजिटरी के सभी अपडेट करता हूं या नहीं।

शुरुआत में स्थापित करने के लिए यह काफी काम था, लेकिन वास्तव में मुझे लंबे समय तक बहुत समय बचाने में मदद मिली।

0

जैसा कि डारिन ने पहले ही बताया है, यदि आपके पास मोक्स हैं तो आपको DI का उपयोग करने की आवश्यकता नहीं है। (हालांकि, डीआई के कुछ अन्य फायदे भी हैं, जिनमें से सबसे पहले, आपके कोड में निर्भरता को कम करना, जो आपके कोड को लंबे समय तक बनाए रखने और विस्तार करने के लिए बहुत आसान बनाता है।)

मैं व्यक्तिगत रूप से सब कुछ तारों को पसंद करता हूं मेरे यूनिट परीक्षणों में, इस प्रकार बाहरी ढांचे, कॉन्फ़िगरेशन फाइल आदि पर जितना संभव हो उतना कम निर्भर करता है

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