2014-10-21 11 views
5

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

_container.Register<IWebServiceOrder>(() => mock.Object, Lifestyle.Transient); 

यह ठीक काम करता है की तरह कंटेनर के लिए वस्तु दर्ज की। लेकिन मेरे परीक्षणों में मैं वेब सेवा के लिए दूसरी कॉल पर सिस्टम के व्यवहार का परीक्षण करना चाहता हूं जिसमें अद्यतन डेटा होगा, इसलिए नकली ऑब्जेक्ट को अपडेट करने की आवश्यकता होगी।

डिफ़ॉल्ट रूप से सरल इंजेक्टर मौजूदा पंजीकरण को ओवरराइड करने की अनुमति नहीं देता है लेकिन आधिकारिक वेबसाइट बताती है कि इस व्यवहार को नीचे की तरह बदलना संभव है।

https://simpleinjector.readthedocs.org/en/latest/howto.html#override-existing-registrations

container.Options.AllowOverridingRegistrations = true; 

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

कंटेनर GetInstance, GetAllInstances करने के लिए पहली कॉल के बाद बदला नहीं जा सकता और

ऐसा क्यों हो रहा है पर कोई भी विचार सत्यापित करें?

+0

देखें [यहां] (https://simpleinjector.readthedocs.org/en/latest/decisions.html#the-container-is-locked-after-the-first-call-to-resolve) कंटेनर क्यों है हल करने के लिए पहली कॉल के बाद बंद कर दिया। – qujck

उत्तर

9

कंटेनर के साथ पहले से ही काम करने के बाद मौजूदा पंजीकरण को बदलने के लिए शायद ही कभी व्यवहार होता है (और यह सभी डी पुस्तकालयों के लिए है) और यही वजह है कि सरल इंजेक्टर कंटेनर लॉक हो गया है। यह अधिक जानकारी here में वर्णित है (जैसा कि @qujck पहले ही इंगित किया गया है)।

सबसे पहले, यदि आप इकाई परीक्षण लिख रहे हैं, तो आपको एक कंटेनर का उपयोग नहीं करना चाहिए। आपका इकाई परीक्षण के लिए खुद को परीक्षण के अंतर्गत वर्ग बनाना चाहिए, या आप इस तरह के रूप में एक सुविधाजनक कारखाने विधि को यह तर्क निकालने,:

private static MailNotifier CreateMailNotifier(
    IDeposit deposit = null, ISendMail mailSender = null, ILog logger = null) 
{ 
    return new MailNotifier(
     deposit ?? Substitute.For<IDeposit>(), 
     mailSender ?? Substitute.For<ISendMail>(), 
     logger ?? Substitute.For<ILog>()); 
} 

इस कारखाने विधि Test Data Builder pattern करने के लिए एक भिन्नता है।

public void Notify_WithValidUser_LogsAMessage() 
{ 
    // Arrange 
    var user = new User(); 

    var logger = new FakeLogger(); 

    MailNotifier sut = CreateMailNotifier(logger: logger); 

    // Act 
    sut.Notify(user); 

    // Assert 
    Assert.AreEqual(expected: 1, actual: logger.LoggedMessages.Count); 
} 

आप एक कंटेनर का उपयोग करते हैं, क्योंकि हाथ से परीक्षण के अंतर्गत वर्ग बनाने भी है:

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

एकीकरण परीक्षण के लिए हालांकि, कंटेनर का उपयोग करना अधिक सामान्य है, लेकिन उस स्थिति में आपको प्रत्येक एकीकरण परीक्षण के लिए बस एक नया कंटेनर बनाना चाहिए। इस तरह आप बिना किसी समस्या के IWebServiceOrder जोड़ या प्रतिस्थापित कर सकते हैं।

+0

ग्रेट उत्तर। यूनिट परीक्षण - नहीं, डी कंटेनर का उपयोग नहीं करना चाहिए, लेकिन एकीकरण टेस्ट - हाँ पूरी तरह से सहमत हैं। मैं सिर्फ ईएफ 6, सरल इंजेक्टर और स्पेकफ्लो के साथ घर पर एक खेल रहा हूं और यह अच्छी तरह से काम करता है - कुछ चीजें हैं जो मैं अपने एकीकरण परीक्षणों में प्रतिस्थापित करना चाहता हूं - मुख्य रूप से डेटटाइम के साथ काम करना - मेरे पास वर्तमान डेटाटाइम प्राप्त करने की सेवा है।काम पर हमारे पास यूनिटी पंजीकरण के लिए एक यूनिट टेस्ट होता है जो धूम्रपान परीक्षण के रूप में अधिक कार्य करता है क्योंकि यह इंजेक्शन कॉन्स्ट्रक्टर का उपयोग करके अमान्य/अपूर्ण पंजीकरण की अनुमति देता है लेकिन यह सभी मुद्दों को सामने लाता है। नोट: हमारे द्वारा उपयोग किए जाने वाले एकता संस्करण के साथ कोई सत्यापन नहीं है। – Andez

+0

@Andrez आप एकता के साथ इस तरह के धूम्रपान परीक्षण में सभी समस्याओं को कठोर रूप से पाएंगे। बस [निदान] (https://simpleinjector.org/diagnostics) को देखें कि सरल इंजेक्टर सत्यापन के दौरान निष्पादित करता है और मुझे बताता है कि क्या आप इस प्रकार की त्रुटियों को एकता के सामने सामने ला सकते हैं। – Steven

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