java एक JUnit परीक्षण में पकड़ने की कोशिश करो




unit-testing try-catch (6)

मैं एक एप्लिकेशन के लिए यूनिट परीक्षण लिख रहा हूं जो पहले से ही लंबे समय से मौजूद है। मेरे द्वारा परीक्षण करने की कुछ विधियाँ इस प्रकार निर्मित हैं:

public void someMethod() throws Exception { 
   //do something 
}

अगर मुझे इन विधियों का परीक्षण करना है तो मुझे अपनी इकाई परीक्षा में कुछ इस तरह लिखना होगा:

@Test
public void someTest() {
   try {
      someMethod();
   }
   catch (Exception e) {
      e.printStackTrace();
   }
}

क्या ऐसा करना एक अच्छा अभ्यास है? या इन तरीकों का परीक्षण करने का एक और तरीका है?

मैंने इंटरनेट पर कुछ शोध किया और मुझे @Rule एनोटेशन और @Test(expected=Exception.class) साथ कुछ समाधान मिले, लेकिन यह काम नहीं कर रहा है (एक्लिप्स टेस्ट में कुछ someMethod() लाइन को गलत someMethod() है)। मुझे नहीं पता कि ये अच्छे समाधान हैं, क्योंकि मैं पूरी इकाई परीक्षण कहानी के लिए बहुत नया हूं।

यदि कोई व्यक्ति जो इस बारे में बहुत कुछ जानता है वह मेरी मदद कर सकता है, तो मैं वास्तव में आभारी रहूंगा।


@Test
public void someTest() {
   try {
     someMethod();
   }
   catch (Exception e) {
     Assert.fail("Exception " + e);
   }
}

क्या आप कर सकते हैं, अगर अपवाद नहीं होना चाहिए। एक विकल्प इस तरह से हस्ताक्षर में अपवाद को फेंकना होगा:

@Test
public void someTest() throws Exception {
     someMethod();
}

अंतर यह है, कि एक मामले में परीक्षण एक अपवाद के साथ विफल हो जाएगा और दूसरे मामले में यह विफल हो जाएगा क्योंकि परीक्षण दुर्घटनाग्रस्त हो गया। (जैसे आपके कोड में कहीं आपको एनपीई मिलता है और परीक्षा उसी वजह से होगी)

ऐसा करने का कारण यह है, क्योंकि अपवाद एक जाँच अपवाद है। चेक किए गए बनाम अनियंत्रित अपवाद देखें

@ टेस्ट (अपेक्षित = एक्सेप्शन.क्लास) परीक्षणों के लिए है, कि परीक्षण करना चाहते हैं कि अपवाद फेंक दिया जाएगा।

@Test(expected=ArrayIndexOutOfBounds.class)
public void testIndex() {
   int[] array = new int[0];
   int var = array[0]; //exception will be thrown here, but test will be green, because we expect this exception

}

चूंकि Exception एक जाँच अपवाद है, आप या तो:

  • एक try...catch में अपवाद को पकड़ने के लिए है try...catch बयान को try...catch , या
  • विधि में ही फेंके जाने वाले अपवाद की घोषणा करें।

आपके पास जो कुछ भी है वह ठीक काम करता है, लेकिन मेरी व्यक्तिगत प्राथमिकता अपवाद को फेंकने की घोषणा करना है। इस तरह, यदि मैं अपवाद की उम्मीद नहीं कर रहा हूं तो परीक्षण के दौरान फेंक दिया जाता है, परीक्षण विफल हो जाएगा।

@Test
public void someTest() throws Exception {
    // dodgy code here
}

अगर हमें यह देखने की ज़रूरत है कि क्या कोई विशेष अपवाद फेंका गया है, तो आपके पास @Rule का उपयोग @Rule या सीधे @Test टिप्पणी एनोटेशन में मान जोड़ने का विकल्प है।

@Test(expected = FileNotFoundException.class)
public void someTest() throws Exception {
    // dodgy code here
}

JUnit 5 में, आप समान चीज़ को पूरा करने के लिए Assertions.expectThrows का लाभ उठा सकते हैं। मैं इस समग्र से कम परिचित हूँ क्योंकि यह संपादन के समय अभी तक जीए नहीं है, लेकिन यह JUIT 5 से आने वाले एक Executable को स्वीकार करता है।

@Test
public void someTest() {
    assertThrows(FileNotFoundException.class, () ->
         { dodgyService.breakableMethod() };
}

JUnit के बारे में तीन बिंदु:

  • टेस्ट सटीक होना चाहिए, उन्हें परीक्षण इनपुट स्थापित करने के तरीके पर पूरी तरह से आधारित पास या असफल होना चाहिए।

  • टेस्ट में विफलताओं की रूपरेखा में रिपोर्ट की जानी चाहिए।

  • टेस्ट को अपने आउटपुट पढ़ने पर भरोसा नहीं करना चाहिए।

आपका उदाहरण तीनों गणनाओं पर विफल है। यदि एक अपवाद फेंक दिया जाता है या नहीं, परीक्षण अभी भी गुजरता है। यदि एक अपवाद को फेंक दिया जाता है तो JUnit इसके बारे में कभी पता नहीं लगाता है और इसे परीक्षा परिणामों में शामिल नहीं कर सकता है। कुछ गलत होने का एकमात्र तरीका यह है कि परीक्षा क्या लिखती है जो स्टडआउट को लिखता है, जिससे त्रुटियों को अनदेखा करना आसान हो जाता है। यह परीक्षण लिखने का एक उपयोगी तरीका नहीं है।

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

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

एकमात्र उदाहरण जहां आप वास्तव में परीक्षण में अपवाद को पकड़ लेंगे, जहां आप अपवाद के बारे में दावे का परीक्षण करना चाहते हैं; उदाहरण के लिए, आप परीक्षण कर सकते हैं कि अपवाद पर संदेश वह है जो आप अपेक्षा करते हैं, या यदि अपवाद के कारण उस पर सेट है। उस स्थिति में आप प्रयास-ब्लॉक के अंत में Assert.fail() जोड़ Assert.fail() ताकि फेंक दिया गया अपवाद न होने से परीक्षण विफल हो जाए।

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


जुनिट परीक्षकों पर अपवादों को संसाधित करने के दो मुख्य नियम हैं:

  1. यदि अपवाद परीक्षण कोड में उत्पन्न हुआ था:

    • यदि यह अपेक्षित था, तो इसे Test एनोटेशन की expected विशेषता में घोषित करें। या, यदि अपवाद ऑब्जेक्ट पर आगे की जांच की जानी चाहिए, तो इसे पकड़ें और इसे अनदेखा करें। (इस मामले में, यह सुनिश्चित करने के लिए कि अपेक्षित अपवाद उत्पन्न नहीं हुआ था, संकेत ब्लॉक के अंत में Assert.fail पर कॉल भी होना चाहिए)।
    • यदि यह अपेक्षित नहीं था, तो इसे पकड़ें और Assert.fail को निष्पादित करें। ( Exception.printStackTrace लिए एक पिछला कॉल भी उपयोगी है)।
  2. यदि अपवाद परीक्षण कोड में उत्पन्न नहीं हुआ था या यह परीक्षण के लिए दिलचस्प नहीं है (उदाहरण के लिए, अधिकांश IOException नेटवर्क स्तर पर उत्पादित किए जाते हैं, इससे पहले कि परीक्षण पूरा भी हो सके), इसे throws क्लॉज़ पर रीथ्रो करें।

आपको परीक्षक में अपवाद की अपेक्षा क्यों करनी चाहिए? याद दिलाएं: आपको परीक्षण कोड (उच्च कोड कवरेज प्राप्त करने के लिए) पर हर संभव परिणाम के लिए एक परीक्षण विधि को कोडित करना चाहिए: आपके मामले में, एक विधि जिसे सफलतापूर्वक लौटना चाहिए, और कम से कम एक और एक अपवाद का उत्पादन करना चाहिए।


अपने परीक्षण कोड में अपने आवेदन के अपवाद को न पकड़ें। इसके बजाय, इसे ऊपर की तरफ फेंकने की घोषणा करें।

क्योंकि, जब JUnit के TestRunner को एक अपवाद मिला है, तो यह स्वचालित रूप से इसे TestRunner लिए एक error रूप में लॉग करेगा।

केवल अगर आप @Test(expected=Exception.class) कि विधि को Exception होना चाहिए तो आपको @Test(expected=Exception.class) उपयोग करना चाहिए या @Test(expected=Exception.class) पकड़ना चाहिए।

अन्य मामलों में, बस इसे ऊपर की ओर फेंकें,

public void someTest() throws Exception {

आप परीक्षण विधि हस्ताक्षर में अपवाद जोड़ सकते हैं। फिर, यदि आप परीक्षण कर रहे हैं कि क्या अपवाद फेंका गया है, तो आपको @Test(expected=Exception.class) । परीक्षण मामलों में जहां अपवाद को फेंकना नहीं है, परीक्षण सफलतापूर्वक पारित होगा।

@Test
public void testCaseWhereExceptionWontBeThrown() throws Exception {
    someMethod(); //Test pass
}

@Test(expected = Exception.class)
public void testCaseWhereExceptionWillBeThrown() throws Exception {
    someMethod(); //Test pass
}




try-catch