2010-01-30 16 views
17

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

इस बारे में कोई विचार कैसे है?

उत्तर

9

सिंगलटन का उपयोग न करें।

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

इसके बजाय, निर्माता को सार्वजनिक बनाएं और नए उदाहरणों का उपयोग करके परीक्षण लिखें। अपने वास्तविक कार्यक्रम में, कैनोलिक वैश्विक उदाहरण प्राप्त करने के लिए getInstance() का उपयोग करें (या एक आईओसी कंटेनर का उपयोग करें)।

और याद रखें कि singletons are pathological liars

यदि आप अभी भी सिंगलटन के विचार से बहुत सहज हैं, तो कन्स्ट्रक्टर को सार्वजनिक करने के बजाय आप एक सार्वजनिक (और स्थैतिक) फैक्ट्री विधि जोड़ सकते हैं ताकि इस तरह के उदाहरण बनाने के लिए दुर्घटना हो, उदाहरण के लिए:

public static MyClass TEST_CreateInstance() { 
    return new MyClass(); 
} 
3

आप सिंगलटन को नष्ट करने के लिए एक विधि जोड़ सकते हैं, उदाहरण के लिए destroyMe(); जहां आप सब कुछ खत्म कर देते हैं और सिंगलटन के उदाहरण को शून्य में सेट करते हैं।

public void destroyMe(){ 
    this.instance = null; 
    //-- other stuff to turn it off. 
} 

मैं हालांकि तुल्यकालन समस्याओं छोड़ देंगे;)

लेकिन तुम क्यों प्रत्येक परीक्षा के लिए अपने सिंगलटन फिर से प्रारंभ करने की आवश्यकता है? यह सिंगलटन की अवधारणा के आधार पर अलग नहीं होना चाहिए।

10

मुझे लगता है कि प्रारंभिक उदाहरण को संग्रहीत करने के लिए आपके सिंगलटन कक्षा में आपके पास एक निजी स्थैतिक क्षेत्र है।

यदि आप अपने कोड को संशोधित नहीं करना चाहते हैं, तो आप प्रत्येक टेस्ट के बाद चलने वाली एक टियरडाउन विधि को परिभाषित कर सकते हैं, और इस विधि में आप इस स्थिर क्षेत्र को here के रूप में प्रतिबिंब के माध्यम से शून्य पर सेट कर सकते हैं।

+1

-1, आईएमओ यह एक वास्तविक समाधान देने के लिए खराब स्थिति बना रहा है – orip

+13

+1। मेरा तीसरा पक्ष कोड पर कोई नियंत्रण नहीं है, जो एक सिंगलटन है, और समाधान की आवश्यकता है, इस पर सलाह नहीं दी जाती कि इसे कैसे किया जाना चाहिए। – eis

1

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

अभी भी प्राप्त करने के लिए जगह में परीक्षण पहले आप कर सकते हैं:

 

static setInstance(...){ //package visibility or in difficult cases you have to use public 
    instance = ...; 
} 
 

के रूप में कहा था कि यह एक समाधान नहीं है। तो पहले परीक्षण स्थान प्राप्त करें, लेकिन फिर सिंगलटन पैटर्न से दूर प्रतिक्रिया दें।

0

सिंगलटन इंस्टेंस को स्वयं परीक्षण द्वारा एसयूटी में पास करने की आवश्यकता है - इस तरह आप प्रत्येक परीक्षण के लिए सिंगलटन (और नष्ट) बनाते हैं। आईओसी को अपनाने और मॉकिटो जैसे मॉकिंग फ्रेमवर्क, इस दृष्टिकोण को लगभग मामूली प्रदान करेगा।

1

मैं अत्यधिक एक डिजाइन पैटर्न के रूप में Singletons से दूर जाने, और एक गुंजाइश (निर्भरता इंजेक्शन) के रूप में सिंगलटन का उपयोग करें। यह आपकी समस्या को दूर कर देगा।

लेकिन यह मानते हुए कि आप सिंगलेटन्स की दुनिया में फंस गए हैं, तो आपके पास सिंगलटन या निर्भरता का परीक्षण करने के आधार पर कुछ विकल्प हैं।

यदि आप निर्भर आइटम का परीक्षण कर रहे हैं तो आप सिंगलटन को PowerMock और JMockIt का उपयोग करके नकल कर सकते हैं। इस बारे में निर्देशों के लिए Runtime.getRuntime पर नकल करने के बारे में मेरे previous post देखें।

यदि आप सिंगलटन का परीक्षण कर रहे हैं तो आपको निर्माण पर नियमों को आराम करने की आवश्यकता है, या सिंगलटन को "रीसेट" विधि दें।

1

वसंत इस विशेष उपयोग मामले के लिए DirtiesContext एनोटेशन प्रदान करता है जहां आपको प्रत्येक टेस्टकेस के लिए सिंगलटन बीन्स के नए उदाहरण की आवश्यकता होती है। यह मूल रूप से प्रत्येक टेस्टकेस/टेस्टक्लास के लिए एक नया अनुप्रयोग संदर्भ बनाता है जिसमें यह एनोटेशन लागू होता है।

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