8

मेरे पास एक एमवीसी वेब ऐप है, और मैं DI के लिए सरल इंजेक्टर का उपयोग कर रहा हूं। लगभग सभी मेरे कोड यूनिट परीक्षणों द्वारा कवर किया गया है। हालांकि, अब मैंने कुछ नियंत्रकों में कुछ टेलीमेट्री कॉल जोड़े हैं, मुझे निर्भरताओं को स्थापित करने में समस्या हो रही है।यूनिट टेस्ट के साथ आवेदन अंतर्दृष्टि का उपयोग करना?

टेलीमेट्री कॉल माइक्रोसॉफ्ट एज़ूर-होस्टेड एप्लिकेशन इनसाइट्स सेवा में मीट्रिक भेजने के लिए हैं। ऐप Azure में नहीं चल रहा है, बस आईएसएस के साथ एक सर्वर। एआई पोर्टल आपको आपके आवेदन के बारे में सभी प्रकार की चीजें बताता है, जिसमें टेलीमेट्री लाइब्रेरी का उपयोग करके आपके द्वारा भेजे जाने वाले किसी भी कस्टम ईवेंट शामिल हैं। नतीजतन, नियंत्रक को माइक्रोसॉफ्ट के एक उदाहरण की आवश्यकता होती है। अनुप्रयोग Insights.TelemetryClient, जिसमें इंटरफेस नहीं है और 2 कन्स्ट्रक्टर के साथ एक सीलबंद वर्ग है। मैं यह इसलिए की तरह दर्ज की कोशिश की (संकर जीवन शैली इस सवाल से संबंधित नहीं है, मैं सिर्फ पूर्णता के लिए यह शामिल है):

 // hybrid lifestyle that gives precedence to web api request scope 
     var requestOrTransientLifestyle = Lifestyle.CreateHybrid(
      () => HttpContext.Current != null, 
      new WebRequestLifestyle(), 
      Lifestyle.Transient); 

     container.Register<TelemetryClient>(requestOrTransientLifestyle); 

समस्या यह है कि जब से TelemetryClient 2 कंस्ट्रक्टर्स है, एसआई की शिकायत है और सत्यापन विफल हो जाता है। मुझे एक पोस्ट मिला जिसमें कंटेनर के कन्स्ट्रक्टर रिज़ॉल्यूशन व्यवहार को ओवरराइड करना है, लेकिन यह बहुत जटिल लगता है। सबसे पहले मैं बैक अप लेना चाहता था और इस सवाल से पूछना चाहता था:

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

इस मुद्दे में कोई भी "अंतर्दृष्टि" बहुत सराहना की जाएगी!

धन्यवाद

+2

मैं सवाल का ऐ पक्ष के साथ मदद नहीं कर सकता लेकिन पंजीकरण करके किया जा सकता है एक प्रतिनिधि को पंजीकृत करना जो एक विशिष्ट कन्स्ट्रक्टर को लक्षित करता है: 'कंटेनर। रजिस्ट्रार (() => नया टेलीमेट्री क्लाइंट (/ * जो भी कन्स्ट्रक्टर आप लक्षित करना चाहते हैं * /), requestOrTransientLifestyle);'। इसके अलावा [डिफॉल्टस्कोप्ड लाइफस्टाइल] (https://simpleinjector.readthedocs.org/en/latest/lifetimes.html#scoped) – qujck

+2

यूनिट परीक्षण के लिए आपको वास्तव में टेलीमेट्री क्लाइंट पर अपने स्वयं के अमूर्तता को परिभाषित करना चाहिए जिसे आप आवश्यकतानुसार नकल कर सकते हैं। यूनिट परीक्षण Azure से बात नहीं करनी चाहिए। – qujck

+0

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

उत्तर

14

Microsoft.ApplicationInsights.TelemetryClient, जो कोई इंटरफ़ेस है और एक सील बंद वर्ग, 2 कंस्ट्रक्टर्स के साथ है।

यह TelemetryClient एक रूपरेखा के प्रकार और framework types should not be auto-wired by your container है।

मुझे एक पोस्ट मिला जिसमें कंटेनर के कन्स्ट्रक्टर रिज़ॉल्यूशन व्यवहार को ओवरराइड करना है, लेकिन यह बहुत जटिल लगता है।

हां, इस जटिलता, जानबूझकर है, क्योंकि हम, कई निर्माताओं के साथ घटक बनाने से लोगों को हतोत्साहित करने के लिए चाहते हैं, क्योंकि यह an anti-pattern है।

इसके बजाय ऑटो तारों का उपयोग करने का

, आप, के रूप में @qujck पहले ही बताया, बस आगे दिए पंजीकरण करा सकते हैं:

container.Register<TelemetryClient>(() => 
    new TelemetryClient(/*whatever values you need*/), 
    requestOrTransientLifestyle); 

या है आवेदन इनसाइट्स बहुत चालाक यह पता करने के लिए एक इकाई में चल रहा है परीक्षण, और डेटा नहीं भेजते हैं?

बहुत ही असंभव। यदि आप इस TelemetryClient पर निर्भर कक्षा का परीक्षण करना चाहते हैं, तो आप अपने यूनिट परीक्षण को नाजुक, धीमा या अपने अंतर्दृष्टि डेटा को प्रदूषित करने के लिए, इसके बजाय नकली कार्यान्वयन का बेहतर उपयोग करते हैं। लेकिन अगर परीक्षण चिंता नहीं है, Dependency Inversion Principle के अनुसार आपको (1) अवशेषों पर निर्भर होना चाहिए जो आपके आवेदन द्वारा परिभाषित (2) हैं। TelemetryClient का उपयोग करते समय आप दोनों बिंदुओं को विफल करते हैं।

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

एक अच्छा अमूर्त परिभाषित करने के बाद, आप एक एडाप्टर कार्यान्वयन बना सकते हैं जो आंतरिक रूप से TelemetryClient का उपयोग करता है। इस प्रकार मैं छवि आप इस अनुकूलक रजिस्टर:

container.RegisterSingleton<ITelemetryLogger>(
    new TelemetryClientAdapter(new TelemetryClient(...))); 

यहाँ मुझे लगता है कि TelemetryClient धागा सुरक्षित है और एक सिंगलटन के रूप में काम कर सकते हैं। अनुकूलक अभी भी एक सिंगलटन है, लेकिन एक प्रतिनिधि है कि TelemetryClient के निर्माण की अनुमति देता के साथ प्रदान की जाती है

container.RegisterSingleton<ITelemetryLogger>(
    new TelemetryClientAdapter(() => new TelemetryClient(...))); 

यहाँ: अन्यथा, आप कुछ इस तरह कर सकते हैं। एक और विकल्प एडाप्टर को TelemetryClient आंतरिक रूप से बनाने (और शायद निपटान) करने देना है। इससे शायद पंजीकरण भी आसान हो जाएगा:

container.RegisterSingleton<ITelemetryLogger>(new TelemetryClientAdapter()); 
+2

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

2

यदि आप अमूर्त/रैपर पथ को नीचे नहीं जाना चाहते हैं। अपने परीक्षणों में आप केवल ऐपइन्साइट्स एंडपॉइंट को एक नकली हल्के http सर्वर (जो एएसपी.नेट कोर में छोटा है) पर निर्देशित कर सकते हैं।

appInsightsSettings.json

"ApplicationInsights": { 
    "Endpoint": "http://localhost:8888/v2/track" 
} 

ASP.NET कोर में "TestServer" स्थापित करने के लिए कैसे http://josephwoodward.co.uk/2016/07/integration-testing-asp-net-core-middleware

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