2011-09-18 13 views
8

पूर्वापेक्षाएँ: मैं Play! framework, और जावा संस्करण (स्कैला नहीं) का नवीनतम संस्करण उपयोग कर रहा हूं।बाहरी सेवाओं के साथ इंटरैक्शन परीक्षण

उपयोगकर्ता द्वारा बनाए जाने पर मुझे संदेश कतार में एक संदेश प्रकाशित करने की आवश्यकता है, और मैं उस व्यवहार का परीक्षण करना चाहता हूं। मेरा मुद्दा यह आसानी से टेस्ट करने योग्य बना रहा है।

नियंत्रक दृष्टिकोण

अन्य चौखटे में, क्या मैं नियंत्रक में निर्माता इंजेक्शन का उपयोग करें और मेरे परीक्षण में एक मज़ाक उड़ाया कतार में पारित करने के लिए किया जाएगा किया है होगा, हालांकि, प्ले के साथ! नियंत्रक स्थिर हैं, इसका मतलब है कि मैं अपने परीक्षणों में new MyController(mockedQueue) नहीं कर सकता।

मैं Google Guice का उपयोग कर सकता हूं और मेरे नियंत्रक में स्थिर क्षेत्र पर @Inject एनोटेशन डाल सकता हूं, लेकिन यह मेरे लिए बहुत अच्छा नहीं लगता है, क्योंकि इसका मतलब है कि मुझे परीक्षण में जगह बदलने के लिए क्षेत्र को सार्वजनिक करना है , या मुझे अपने परीक्षणों में एक कंटेनर का उपयोग करना है। मैं कन्स्ट्रक्टर इंजेक्शन का उपयोग करना पसंद करूंगा, लेकिन खेलो! ऐसा करने के लिए प्रतीत नहीं होता है।

मॉडल दृष्टिकोण

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

अगर मैं अपनी इकाई को कतार में कॉल करता हूं, तो यह कैसे टेस्टेबल है?

बेशक, अगर मैं एंड-टू-एंड एकीकरण परीक्षण करता हूं तो ये दोनों स्थितियां अनावश्यक हैं, लेकिन मुझे अपने परीक्षणों के लिए संदेश कतार या एसएमटीपी सर्वर की आवश्यकता नहीं है।

तो मेरा प्रश्न है: मैं अपने Play को कैसे मॉडल करूं! बाहरी सेवाओं के साथ परीक्षण इंटरैक्शन की सुविधा के लिए नियंत्रक और/या मॉडल?

उत्तर

3

जैसा कि मैंने देखा, इसके लिए एक साफ समाधान नहीं है।

आप अपनी निर्भरताओं के लिए Abstract Factory का उपयोग कर सकते हैं। इस कारखाने में उत्पन्न वस्तुओं के लिए सेटटर विधियां हो सकती हैं।

public class MyController { 
    ... 
    private static ServiceFactory serviceFactory = ServiceFactory.getInstance(); 
    ... 
    public static void action() { 
     ... 
     QueueService queue = serviceFactory.getQueueService(); 
     ... 
    } 

}

आपका परीक्षण इस प्रकार दिखाई देगा:

public void testAction() { 
    QueueService mock = ... 
    ... 
    ServiceFactory serviceFactory = ServiceFactory.getInstance(); 
    serviceFactory.setQueueService(mock); 
    ... 
    MyController.action(); 
    verify(mock); 
} 

आप कारखाने के सेटर तरीकों का खुलासा नहीं करना चाहते हैं, तो आप एक इंटरफेस बनाने और कॉन्फ़िगर कर सकता है को लागू करने आपके परीक्षण में कक्षा।

एक और विकल्प स्थिर तरीकों का मज़ाक उड़ाने के लिए PowerMock का उपयोग करेगा। मैंने पहले उपयोग किया है और यह ज्यादातर मामलों के लिए अपेक्षाकृत ठीक काम करता है। बस इसे अधिक उपयोग न करें, या आप रखरखाव नरक में हैं ...

और आखिरकार, चूंकि आप अपने आवेदन में गुइस का उपयोग करने के इच्छुक हैं, this एक व्यवहार्य विकल्प हो सकता है।

शुभकामनाएं!

+0

दिमाग में बेहतर स्पष्टीकरण के साथ अद्यतन उत्तर 'सेवा फैक्टरी' दृष्टिकोण के साथ एक * संभावित * मुद्दा तब होता है जब फ़ील्ड प्रारंभ किया जाएगा; चूंकि यह एक स्थिर क्षेत्र है, उदाहरण प्राप्त करने का मौका मिलने से पहले 'getInstance' को प्रारंभकर्ता द्वारा बुलाया जा सकता है। बस जोर से सोचते हुए, वास्तव में यह सत्यापित नहीं किया। –

+0

असल में, उदाहरण में, सर्विसफैक्टरी एक सिंगलटन है। आप स्वयं सेवाफैक्टरी को प्रतिस्थापित नहीं करेंगे, लेकिन क्यूई सेवा जो इसे 'उत्पादन' करती है। –

+0

हाँ, मैं समझता हूं; हालांकि, जैसा कि क्षेत्र स्थैतिक है, वहां संभावना है कि इससे पहले कि आप 'getInstance' से वापस लौटाए गए मूल्य को प्रतिस्थापित करने में सक्षम हो जाएं। स्थैतिक प्रारंभकर्ता निष्पादित होने पर आपके पास आमतौर पर नियंत्रण नहीं होता है, इसलिए यह आपके परीक्षण सेटअप होने से पहले हो सकता है। –

2

मैं थोड़ा उलझन में हूं। आप एक नकली प्रयोग करने के लिए QueueService अन्य वर्ग

public class Users extends Controller { 
    public static void save(@Valid User user) { 
    //check for user validaton 
    user = user.save(); 
    QueueService queueService = new QueueSerice(); 
    queueService.publishMessage(user); 
    } 
} 

आप इकाई testcases लिख सकते हैं की एक विधि कॉल और उपयोगकर्ता नियंत्रक बचाने विधि के लिए कार्यात्मक testcase लिख सकते हैं।

+0

शायद मैं स्पष्ट नहीं था। आप अपने परीक्षण में नकली उदाहरण के साथ 'नई QueueService()' को कैसे बदल देंगे? या आप कह रहे हैं कि आप यूनिट 'क्यूई सेवा' का परीक्षण करेंगे, लेकिन केवल 'उपयोगकर्ता' और 'क्यूई सेवा' के बीच बातचीत का कार्यात्मक परीक्षण करेंगे? –

+0

अगर यह जाने का रास्ता है, ठीक है; लेकिन अधिकांश अन्य ढांचे में मैंने निपटाया है, बिना किसी वास्तविक लाइव कतार उपलब्ध होने के लिए दोनों के बीच बातचीत का परीक्षण करना पूरी तरह से व्यवहार्य है। –

2

संपादित करें: जवाब का विस्तार के रूप में पिछले स्पष्ट नहीं था

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

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

"कुंजी" यहां "संसाधित होने के अनुरोध को भेजें" है।कुछ मामलों में हम कंट्रोलर में यह काम कर सकते हैं यदि यह आसान है, लेकिन अन्य मामलों में यह "सेवा" (किसी भी तरह से कॉल करने के लिए) का उपयोग करना बेहतर लगता है जिसमें आप दिए गए डेटा के साथ काम करते हैं।

मैं इस पृथक्करण का उपयोग परीक्षण के दृष्टिकोण से (मेरे लिए) सेलेनियम के माध्यम से नियंत्रक का परीक्षण करने के लिए करता हूं और सेवा के लिए एक अलग परीक्षण (जुनीट का उपयोग करके) करता हूं।

आपके मामले में इस सेवा में आपके द्वारा उल्लेखित कतार का संदर्भ शामिल होगा।

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

आशा है कि यह अद्यतन जब मैंने उत्तर दिया तो मेरे मन में जो कुछ भी था, उसे स्पष्ट करता है।

+0

चिकन और अंडा। तो फैक्ट्री कहां से आती है? एक सिंगलटन? –

+0

चिकन और अंडा? : | आपके पास सिंगलटन या यूटिलिटी क्लास या कहीं कहीं एक स्थिर फैक्ट्री विधि हो सकती है। इसका एकमात्र उद्देश्य आपको आवश्यक कतार वस्तु को वापस करना है। मेरा मतलब है, आप इसे और किस तरह से करना चाहते हैं? मुझे डर है कि मुझे समस्या नहीं दिखाई दे रही है या मैं आपकी आपत्ति को समझ नहीं पा रहा हूं। –

+0

किसी भी अन्य ढांचे में, मैं कन्स्ट्रक्टर इंजेक्शन (कंटेनर के साथ या बिना) का उपयोग करता हूं। सिंगलेट या फैक्ट्री विधियों का उपयोग केवल कक्षा को वास्तव में किस निर्भरता को छिपाने के लिए काम करता है। –

1

शायद यह नहीं है कि आप क्या खोज रहे हैं, लेकिन मेरे वर्तमान प्रोजेक्ट में हमने एकीकरण परीक्षण के माध्यम से परीक्षण और स्थानीय कतार और एक संदेश पुल के साथ एक जेएमएस सेटअप हल किया है।

थोड़ा और अधिक विस्तार में:

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

अपने प्रोजेक्ट पर, हम SoapUI का उपयोग परीक्षण के अंतर्गत प्रणाली के रूप में इन परीक्षणों प्रदर्शन करने के लिए एक सोप आधारित एकीकरण मंच है और SoapUI अच्छा JMS समर्थन हासिल है। लेकिन यह एक सादा जुनीट परीक्षण भी हो सकता है जो परीक्षण करता है और बाद में स्थानीय जेएमएस कतार से पढ़ता है।

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