2010-05-14 15 views
16

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

मैं जुनीट को अपने धागे को पूरा करने के लिए बाल धागे की प्रतीक्षा करने के लिए कैसे मजबूर करूं?

धन्यवाद

उत्तर

7

प्रश्न पढ़ने और कुछ टिप्पणियों के बाद, ऐसा लगता है कि आपको जो चाहिए वह इकाई परीक्षण एसिंक्रोनस ऑपरेशंस के लिए एक तकनीक है। doSomething() तुरंत लौटता है, लेकिन आप परीक्षण कोड को पूरा होने के लिए प्रतीक्षा करना चाहते हैं, और फिर कुछ मान्यताओं को करें।

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

1) एक श्रोता एक बार आपरेशन

2 पूरा हो गया है अधिसूचित हो जाता है कि) ऑपरेशन का एक तुल्यकालिक संस्करण उपलब्ध कराना दर्ज की अनुमति दें। कार्यान्वयन एसिंच संस्करण को कॉल कर सकता है, और तब पूरा होने तक ब्लॉक कर सकता है। यदि कक्षा ऐसी विधि को उजागर नहीं करनी चाहिए, तो इसकी दृश्यता को पैकेज में सुरक्षित किया जा सकता है, ताकि परीक्षण इसे एक्सेस कर सके।

3) कुछ दृश्यमान वस्तु पर प्रतीक्षा-सूचना पैटर्न का उपयोग करना।

यदि कक्षा ऐसी कोई व्यवस्था प्रदान नहीं करती है, तो यह वास्तव में परीक्षण योग्य नहीं है, और इससे भी बदतर, यह शायद बहुत पुन: प्रयोज्य नहीं है।

2

बनाया धागे पर thread.join() का उपयोग करें। यह उस थ्रेड के मरने की प्रतीक्षा करेगा।

संपादित करें: इससे बचने के लिए, परीक्षण में Thread.getThreadGroup().setDaemon(true); या शायद setUp() विधि में आज़माएं। हालांकि मैंने इसका परीक्षण नहीं किया है।

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

मुझे आश्चर्य है कि क्या जुनीट System.exit() पर कॉल कर रहा है या जैसे ही परीक्षण खत्म हो जाता है।

+0

वास्तव में मैं इस समाधान से बचूंगा, इसके बजाय मैं इस तरह के परीक्षण चलाने के लिए एक बेहतर तरीका ढूंढ रहा था और मुख्य धागे को अपने बच्चों के अंत की प्रतीक्षा करने के लिए मजबूर कर रहा था। – Mark

+0

@ मार्को: क्या आप विस्तृत कर सकते हैं? क्रिस के समाधान के साथ क्या गलत है? –

+0

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

0

शायद समूह एक ExecutorService के साथ अपने सूत्र, तो बंद और awaitTermination विधि का उपयोग करें?

स्थिति रननेबल या भविष्य का उपयोग करना है, न कि थ्रेड स्वयं।

+1

जुनीट निष्पादक सेवा समाप्त करने की प्रतीक्षा नहीं करता है। – koppor

1

मूल तकनीक जो @Eyal रूपरेखा है ConcurrentUnit का उद्देश्य है।सामान्य उपयोग है:

  1. स्पोन कुछ धागे
  2. मुख्य थ्रेड प्रतीक्षा है या सो
  3. कार्यकर्ता धागे के भीतर से दावे को पूरा करें (जो ConcurrentUnit के माध्यम से, वापस मुख्य थ्रेड पर रिपोर्ट कर रहे हैं)
  4. एक बार सभी दावों को पूरा करने के बाद कार्यकर्ता धागे में से एक से मुख्य धागे को फिर से शुरू करें

अधिक जानकारी के लिए ConcurrentUnit पृष्ठ देखें।

0
 while (s.isRunning()) { 
      try { 
       Thread.sleep(SLEEP_TIME); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

आप जुनीट थ्रेड को अवरुद्ध करने का प्रयास कर सकते हैं और इसे अपने थ्रेड को पूरा करने की प्रतीक्षा कर सकते हैं। Thread.sleep() की आवश्यकता है ताकि आपका धागा CPU को हॉग न करे। इस उदाहरण में आपका धागा होगा आपको isRunning() विधि की आवश्यकता होगी ताकि आप यह जांच सकें कि थ्रेड अभी भी SLEEP_TIME मिलीसेकंड चला रहा है या नहीं। मुझे पता है कि यह सबसे बड़ा समाधान नहीं है, लेकिन यदि आपके पास केवल 2 धागे हैं और आप नहीं चाहते हैं कि जुनीट ने आपके धागे को मार डाला है। इस जुनीट धागे को जीवित रहने के कारण और आपके अन्य धागे को समाप्त करने का इंतजार करने के कारण थोड़ी देर लूप।

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