क्या यूनिट परीक्षण के लिए निर्भरता इंजेक्शन आवश्यक है?


55

यूनिट परीक्षण के लिए निर्भरता इंजेक्शन (DI) का उपयोग करना आवश्यक है?

मैं कोड को अलग करने के लिए एक और विकल्प के बारे में नहीं सोच सकता, इसलिए इसका परीक्षण किया जा सकता है। इसके अलावा, मैंने कभी देखा है सभी उदाहरण इस पैटर्न का उपयोग करते हैं। क्या इसलिए कि यह एकमात्र व्यवहार्य विकल्प है या अन्य विकल्प हैं?


5
निर्भरता इंजेक्शन आवश्यक नहीं है, लेकिन नियंत्रण के व्युत्क्रम की व्यापक अवधारणा है।
जेरेमी हीलर

यहाँ पैमाने के लिए कुछ कहा जाना है। अगर मेरे पास बहुत कम परतों के साथ एक छोटा कोड आधार है तो DI उपयोगी नहीं हो सकता है।
जेबी राजा

@JBKing यदि आपके पास एक छोटा कोड आधार है, तो आपको परतों या इकाई परीक्षण की आवश्यकता नहीं है
Sklivvz

1
आपके कोड को परीक्षण योग्य बनाने के लिए बहुत सारे डिज़ाइन निर्णय आवश्यक हैं। परीक्षण लिखना शुरू करें और पता करें।
नाथन कूपर

जवाबों:


42

DI इकाई परीक्षण को बहुत आसान बनाता है। लेकिन आप अभी भी बिना डीआई के यूनिट टेस्ट लिख सकते हैं। डीआई के व्यापक होने से पहले ही बहुत सारे यूनिट टेस्ट लिखे जा चुके हैं। (बेशक, इनमें से कुछ तकनीक का उपयोग डीआई के समान या बहुत ही समान है, बिना यह जाने कि यह एक फैंसी नाम है :-)

मैंने खुद DI के बारे में जानने से पहले बहुत सारे इंटरफेस और कारखानों का इस्तेमाल किया है। वास्तविक फ़ैक्टरी क्लास का नाम एक कॉन्फ़िगरेशन फ़ाइल से पढ़ा जा सकता है, या एक तर्क के रूप में SUT को दिया गया।

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

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


सहमत, DI विशेष रूप से वस्तुओं को मॉक करने के लिए उपयोगी है। लेकिन ऐसे कई परिदृश्य हैं जहां DI परीक्षणों में बेकार है।
केमोडा

@ Kemoda उदाहरण के लिए क्या?
B43ови

@VJovic उदाहरण के लिए स्टैंडअलोन ऑब्जेक्ट्स। मैं एक ऐसी विधि के बारे में सोचता हूं, जो कुछ तर्क देती है और कुछ चीजें करती है, लेकिन दूसरे घटक पर निर्भर नहीं करती है (इस प्रकार DI की कोई आवश्यकता नहीं है)।
केमोडा

@Kemoda ऐसा लगता है कि आप कार्यात्मक प्रोग्रामिंग का वर्णन कर रहे हैं, और आप DI का उपयोग कर रहे हैं। आप अपनी निर्भरता को विधि मापदंडों के रूप में इंजेक्ट कर रहे हैं।
एरिक डिट्रिच

3
@ ह्यूगी, कार्यान्वयन विवरण यहां क्यों लीक हो जाएगा? निर्भरता इंजेक्शन आमतौर पर एक इंटरफ़ेस के पीछे छिपा हुआ है, और पूरे बिंदु यह है कि ग्राहक वर्ग का कोई पता नहीं है - और इसका कोई संबंध नहीं है - क्या इस निर्भरता का वास्तविक कार्यान्वयन एक वास्तविक उत्पादन वर्ग या नकली है। इसकी तात्कालिकता ग्राहक वर्ग के बाहर होती है, यह केवल तैयार किए गए उदाहरण को देखने के लिए मिलती है।
पाटर तोक

56

यूनिट टेस्टिंग के लिए Decoupling जरूरी है। डीआई डिकोडिंग प्राप्त करने का एक शानदार तरीका है।


17
एक बहुत ही सच्चा बयान जो किसी भी तरह से सवाल का जवाब नहीं देता है।
ट्रैविस

10

आपके द्वारा उपयोग की जा रही तकनीकों के आधार पर, आप DI का उपयोग किए बिना निर्भरता को अलग कर सकते हैं। उदाहरण के लिए, .NET दुनिया में, मोल्स आपको DI पैटर्न के बिना निर्भरता को अलग करने की अनुमति देता है।

मैंने कहा, मेरा मानना ​​है कि ये अलगाव रूपरेखा बाहरी निर्भरता (फाइल सिस्टम, डेटाबेस, आदि) के साथ आपके कोड में स्थितियों के लिए लिखी गई है। यही कारण है कि, तथ्य यह है कि यह कर सकता है इसका मतलब यह नहीं है कि वह या वह करना चाहिए।

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


3
या मोल्स आपको लगता है कि आप साफ, अच्छी तरह से सचित्र परीक्षण योग्य कोड प्राप्त कर लेते हैं क्योंकि आप जादू के माध्यम से परीक्षण कर रहे हैं।
व्याट बार्नेट

@YattBarnett हाँ, बहुत सही है। मोल्स में किसी को कहने के लिए एक विन्स-उत्प्रेरण क्षमता है "जो इस बहुरूपता और खुले / बंद सामान की सभी को जरूरत है, वैसे भी?"
एरिक डायट्रिच

1
मोल्स ने उनकी जगह ली नकली , और नकली पृष्ठ से "नकली ढांचे में डेवलपर की सहायता उनके इकाई परीक्षण में बनाने, रखरखाव, और इंजेक्षन डमी कार्यान्वयन" मेरे लिए डि की तरह लगता है।
हस्ताक्षर करें

1
@Sign आपका लिंक यह भी कहता है, "नकली ढांचे को किसी भी .NET विधि को शिम करने के लिए इस्तेमाल किया जा सकता है, जिसमें गैर-आभासी और सीलबंद तरीकों में स्थिर तरीके शामिल हैं।" तथ्य यह है कि अलगाव चौखटे डि साथ संयोजन के रूप में इस्तेमाल किया जा सकता मतलब यह नहीं है कि वे कर रहे हैं डि।
एरिक डायट्रिच

4

नहीं, यूनिट परीक्षण के लिए DI आवश्यक नहीं है, लेकिन यह बहुत मदद करता है।

आप कारखानों या लोकेटर का उपयोग कर सकते हैं और परीक्षण कर सकते हैं जैसा कि आप डि के साथ करेंगे (बस उतना ही सुरुचिपूर्ण नहीं है और अधिक सेटअप की आवश्यकता होगी)।

इसके अलावा, मॉक ऑब्जेक्ट्स विरासत प्रणालियों में महत्वपूर्ण होंगे जहां कई कॉल निर्भरता के बजाय फ़ंक्शंस को सौंपे जाते हैं। (नकली वस्तुओं का बड़े पैमाने पर उचित सेटअप में भी उपयोग किया जा सकता है)

वहाँ सेटअप हो सकते हैं जहाँ परीक्षण लगभग असंभव है। लेकिन यह इस पर आधारित नहीं है कि निर्भरता इंजेक्शन का उपयोग किया जाता है या नहीं।


3

नहीं , यूनिट परीक्षण के लिए निर्भरता इंजेक्शन आवश्यक नहीं है।

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

उदाहरण (DI का उपयोग करते हुए) यह कार्यान्वयन कर्मचारी, खाता, ... पर निर्भर करता है

 bool hasPermissionToTransferMoney(Employee employee, Account from, Account to, Money amount)
 {
     if (amount > 100 && employee.isStudent())
        return false;
     if (to.getOwner().getFamiliyName() == employee.getFamilyName() && ...
        return false; // cannot transfer money to himself;
     ...
 }

डेटा एकत्र करने और गणना के अलग होने के बाद:

 bool hasPermissionToTransferMoney(Employee employee, Account from, Account to, Money amount)
 {
     return hasPermissionToTransferMoney(employee.isStudent(), employee.getFamilyName(), to.getOwner().getFamilyName(), ...);
 }

 // the actual permission calculation
 static bool hasPermissionToTransferMoney(boolean isStudent, string employeeFamilyName, string receiverFamilyName, ...)
     if (amount > 100 && isStudent)
        return false;
     if (receiverFamilyName == employeeFamiliyName && ...
        return false; // cannot transfer money to himself
     ...
 }

गणना भाग आसानी से निर्भरता इंजेक्शन के बिना परीक्षण किया जा सकता है।


1
  • यूनिट परीक्षण के लिए निर्भरता इंजेक्शन आवश्यक नहीं है

  • जब आप दूसरे के लिए एक कार्यान्वयन स्वैप करना चाहते हैं तो दूसरी ओर नियंत्रण का उलटा होना आवश्यक है।


0

हां, अलगाव के लिए डीआई के उपयोग के विकल्प हैं।

एक विकल्प कारखानों या एक सेवा-प्रदाता का उपयोग करना है जो वास्तविक लोगों के बजाय नकली वस्तुओं को वापस करने के लिए परीक्षण से कॉन्फ़िगर किया जा सकता है।

एक अन्य उपयुक्त अलगाव फ्रेमवर्क या मॉकिंग टूल का उपयोग करना है। ऐसे उपकरण हर आधुनिक प्रोग्रामिंग भाषा (जावा, C #, रूबी और पायथन के लिए, कम से कम) के लिए मौजूद हैं। वे अन्य वर्गों / प्रकारों के कार्यान्वयन से परीक्षण किए जा रहे एक वर्ग को अलग कर सकते हैं, तब भी जब परीक्षण किया गया वर्ग सीधे अपनी निर्भरता का संकेत देता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.