2012-04-13 35 views
12

जावा/जुनीट में, मुझे कुछ ऑब्जेक्ट के साथ शून्य के लिए परीक्षण करने की आवश्यकता है। ऐसे कई तरीके हैं जिन पर मैं एक शर्त का परीक्षण कर सकता हूं लेकिन मैं अपने अधिकांश परीक्षणों के लिए assertTrue का उपयोग कर रहा हूं। जब मैं एक assertTrue में नल की जांच करता हूं, EclEmma कहता है कि यह केवल एक शाखा का परीक्षण कर रहा है।assertTrue का उपयोग करते समय ग़लत शाखाएं assertTrue के बजाय

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

ऐसा क्यों हो रहा है? क्या यह अतिरिक्त बाइट कोड से संबंधित है जो जावा स्पष्ट रूप से http://sourceforge.net/apps/trac/eclemma/wiki/FilteringOptions पर उल्लिखित के रूप में जोड़ता है? कोई समाधान (अन्य जोर बयान का उपयोग करने के अलावा)।

assertTrue:

assertTrue(myObject == null); //1 of 2 branches 

assertTrue:

boolean test = (myObject == null); //1 of 2 branches missing 
assertTrue(test); // complete 

assertNull:

assertNull(myObject) //complete; 
+1

क्या assertNull का उपयोग करके अशक्त जोर देते हुए साथ कुछ गड़बड़ है बूलियन तरीकों पर 100% कोड कवरेज प्राप्त करने के लिए? आम तौर पर उस चीज के लिए उचित जोर प्रकार का उपयोग करना बेहतर होता है जो जोर दिया जाता है। परीक्षण बेहतर में खुदाई किए बिना परीक्षण विफल होने पर आप बेहतर सोचते हैं कि क्या गलत है। – nansen

+0

@ नैनसेन यह सच है और अगर मुझे आवश्यकता है तो मुझे assertNull का उपयोग करने में कोई समस्या नहीं है, हालांकि, आईएमओ, सभी "प्रकार" जोर देते हैं, केवल एक अन्य प्रकार का दावा है। अलग-अलग assert प्रकारों जैसे अतिरिक्त त्रुटि जानकारी/पठनीयता का उपयोग करने के लिए अतिरिक्त लाभ हो सकते हैं लेकिन यह वास्तव में यहां कोई समस्या नहीं है। –

+0

@ नैनसेन यह कहना नहीं है कि मैं assertNull का उपयोग करने से इनकार करता हूं और शायद इसका उपयोग कर रहा हूं, मुझे बस यह विशेष समस्या दिलचस्प लगता है क्योंकि मैं मूल रूप से एक ही चीज़ के लिए परीक्षण कर रहा हूं लेकिन एम्मा पूरी तरह से अलग-अलग परिणाम देती है। –

उत्तर

16

सबसे बूलियन expressi के लिए ऑन, जावा कंपाइलर बाइट कोड में अतिरिक्त शाखाएं उत्पन्न करता है। JaCoCo जेनरेट बाइट कोड के आधार पर "शाखा कवरेज" उत्पन्न करता है, मूल जावा कोड के आधार पर नहीं, और इसलिए आप उपयोग की जाने वाली किसी भी बूलियन अभिव्यक्ति के लिए अतिरिक्त शाखा कवरेज जानकारी दिखाता है।

आपके कोड में, आपके द्वारा उपयोग की जाने वाली बूलियन अभिव्यक्ति myObject == null है।

इस मान की गणना करने के लिए, जावा कंपाइलर स्टैक पर दो तर्कों को धक्का देने वाला कोड उत्पन्न करता है, और फिर स्टैक पर 1 (सत्य) या 0 (झूठी) को धक्का देने के लिए एक सशर्त कूद कर देता है। जाकोको इस सशर्त कूद की शाखा कवरेज की रिपोर्ट करता है।

इस प्रकार, आप जिस तथ्य का उपयोग करते हैं myObject == null आपके द्वारा वर्णित व्यवहार को ट्रिगर करता है।

कुछ अन्य उदाहरण के रूप में, इस प्रयास करें:

boolean t = true; 
boolean f = false; 
boolean result1 = (t && f) || f; // 3 out of 6 missed. 
boolean result2 = !t;   // 1 out of 2 missed. 

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

यह सुविधा भी अच्छी तरह से प्रलेखित नहीं है, लेकिन यहां कुछ संकेत दिए गए हैं:

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

नोट: प्रारंभिक उत्तर के बाद से प्रमुख EDIT अनुमान लगाया गया था। & महत्वपूर्ण चर्चा के लिए @ इरा-बैक्सटर का धन्यवाद।

1

तथ्य यह है कि एम्मा आईएमएचओ की गिनती (शाखा) कवरेज के लिए "शाखा के साथ कुछ" के रूप में एक सशर्त अभिव्यक्ति का इलाज करती है। यह एक सशर्त शाखा नहीं है।

हम जोर के बारे में अधिक बहस कर सकते हैं; अगर इसे "विफलता पर जोर देने पर अपवाद फेंक दिया गया" के रूप में परिभाषित किया गया था तो यह वास्तव में एक conditonal शाखा है; यदि यह परिभाषित किया गया है [जैसा कि मुझे लगता है कि मैं करता हूं, मैं जावा विशेषज्ञ नहीं हूं] "विफलता पर मेरा कार्यक्रम समाप्त करें" के रूप में यह वास्तव में एक शाखा नहीं है। विधि कॉल भी अस्पष्ट हैं; ये सशर्त शाखाएं इस अर्थ में हैं कि यदि बुलाया गया तरीका अपवाद फेंकता है, तो नियंत्रण प्रवाह "शेष बयान" जारी नहीं रहता है।

हमारे Java Test Coverage उपकरण ऐसी परिस्थितियों पर "शाखा" कवरेज विश्लेषण प्राप्त करता है "दाएं"।

+0

JUnit API से assertTrue/assertNull विधियों के बारे में कुछ भी खास नहीं है। अगर वे स्थिति पकड़ नहीं लेते हैं तो वे सिर्फ java.lang.Assertion त्रुटि को फेंक देते हैं। यह जावा के 'जोर' कीवर्ड से सीधे संबंधित नहीं है। – avandeursen

+0

मैं इस बात से सहमत हूं कि इस एम्मा/जाकोको सुविधा * शाखा कवरेज * को कॉल करना (बहुत) भ्रमित है। (अलग) कवरेज जानकारी मुझे किसी भी बूलियन (उप) अभिव्यक्ति के लिए बता रही है कि क्या यह सत्य और गलत दोनों का मूल्यांकन किया गया है, हालांकि यह एक उपयोगी विशेषता है। – avandeursen

+0

@avandeursen: यह निर्धारित करना कि प्रोग्राम में प्रत्येक * शर्त * का प्रयोग "सत्य" या "झूठा" के रूप में किया गया है, शाखा कवरेज नहीं है; यह "हालत कवरेज" है। निश्चित रूप से हमारा उपकरण हालत कवरेज नहीं करता है; पिछली समझ के आधार पर, मुझे विश्वास नहीं है कि एम्मा हालत कवरेज करती है, लेकिन मुझे आश्चर्यचकित किया जा सकता है। –

0

, निम्न कार्य करें

Class RecordService{ 


    public boolean doesRecordExist(String id){ 

    return id!=null; 

    } 


    } 

    //Method inside your mock 
    @Test 
    public boolean testDoesRecordExist(){ 
    RecordService recordService = mock(RecordService.class); 
    when(recordService.doesRecordExists()).thenReturn(
        anyString()).thenReturn(null); 

    }