2010-06-21 19 views
15

संपादित करें: इस समय JUnit 4 उपलब्ध नहीं है।जुनीट अपवाद परीक्षण

नमस्ते,

मैं JUnit के साथ "स्मार्ट" अपवाद परीक्षण के बारे में एक प्रश्न है। इस समय, मैं इसे इस तरह कार्य करें:

public void testGet() { 

    SoundFileManager sfm = new SoundFileManager(); 

     // Test adding a sound file and then getting it by id and name. 
     try { 
      SoundFile addedFile = sfm.addSoundfile("E:\\Eclipse_Prj\\pSound\\data\\Adrenaline01.wav"); 
      SoundFile sf = sfm.getSoundfile(addedFile.getID()); 
      assertTrue(sf!=null); 
      System.out.println(sf.toString()); 

      sf = sfm.getSoundfileByName("E:\\Eclipse_Prj\\pSound\\data\\Adrenaline01.wav"); 
      assertTrue(sf!=null); 
      System.out.println(sf.toString()); 
     } catch (RapsManagerException e) { 
      System.out.println(e.getMessage()); 
     } 

     // Test get with invalid id. 
     try { 
      sfm.getSoundfile(-100); 
      fail("Should have raised a RapsManagerException"); 
     } catch (RapsManagerException e) { 
      System.out.println(e.getMessage()); 
     } 

     // Test get by name with invalid name 
     try { 
      sfm.getSoundfileByName(new String()); 
      fail("Should have raised a RapsManagerException"); 
     } catch (RapsManagerException e) { 
      System.out.println(e.getMessage()); 
     } 

    } 

आप देख सकते हैं, मैं एक समारोह है कि एक अपवाद फेंकने के लिए माना जाता है के लिए एक आज़माएं/कैच ब्लॉक की जरूरत है। ऐसा करने का यह एक अच्छा तरीका नहीं है - या कोशिश/पकड़ के उपयोग को कम करने की कोई संभावना नहीं है?

+0

मैं परीक्षण के अंदर System.out.println कर के खिलाफ सुझाव है। System.out और System.err मिश्रण और गड़बड़ परीक्षण आउटपुट का उत्पादन करते हैं। – RockyMM

उत्तर

31

मेरा सुझाव है कि आप अधिक अलग-अलग परीक्षण में testGet को तोड़ने की जरूरत है। व्यक्ति कोशिश/पकड़ ब्लॉक एक दूसरे से बहुत स्वतंत्र प्रतीत होता है। आप सामान्य प्रारंभिक तर्क को अपनी सेटअप विधि में भी निकालना चाहते हैं।

एक बार जब आप गए हैं, आपको JUnit4 के अपवाद एनोटेशन समर्थन उपयोग कर सकते हैं, कुछ इस तरह:

public class MyTest { 

private SoundManager sfm; 

@Before 
public void setup() { 
     sfm = new SoundFileManager(); 
} 

@Test 
public void getByIdAndName() { 
    // Test adding a sound file and then getting it by id and name. 
     SoundFile addedFile =    
     sfm.addSoundfile("E:\\Eclipse_Prj\\pSound\\data\\Adrenaline01.wav"); 
     SoundFile sf = sfm.getSoundfile(addedFile.getID()); 
     assertTrue(sf!=null); 
     System.out.println(sf.toString()); 

     sf = sfm.getSoundfileByName("E:\\Eclipse_Prj\\pSound\\data\\Adrenaline01.wav"); 
     assertTrue(sf!=null); 
     System.out.println(sf.toString()); 
} 

@Test(expected=RapsManagerException.class) 
public void getByInvalidId() { 
     // Test get with invalid id. 
     sfm.getSoundfile(-100); 
} 

@Test(expected=RapsManagerException.class) 
public void getByInvalidName() { 
     // Test get with invalid id. 
     sfm.getSoundfileByName(new String()); 
} 
} 
+0

मुझे यह पसंद है, लेकिन मुझे एक चल रहे प्रोजेक्ट में जुनीट 4 पर स्विच करने से डर है। – InsertNickHere

+4

@InsertNickHere: आपकी सावधानी सराहनीय है, लेकिन मैं इस मामले में गलत जगह का सुझाव देता हूं। JUnit4 परिवर्तन के बिना जुनीट 3-स्टाइल परीक्षण चला सकता है, जिससे आप धीरे-धीरे एक परीक्षण में माइग्रेट कर सकते हैं। इसके अलावा, जुनीट 4 अब 4 साल का है, यह वास्तव में समय है जब आप चले गए। – skaffman

+1

मुझे पूरी तरह से आपसे सहमत होना है- इस मामले में मुझे जुनीट 4 में स्थानांतरित करना होगा। – InsertNickHere

3

JUnit 4 के साथ, आप एनोटेशन के बजाय का उपयोग कर सकते हैं। हालांकि, साफ-सफाई के लिए आपको अपने परीक्षण को 3 अलग-अलग तरीकों से अलग करना चाहिए। ध्यान दें कि पहले परिदृश्य में अपवाद को पकड़ने वाला IMHO विफल होना चाहिए, इसलिए मैंने तदनुसार catch ब्लॉक को संशोधित किया।

public void testGet() { 
    SoundFileManager sfm = new SoundFileManager(); 

    // Test adding a sound file and then getting it by id and name. 
    try { 
     SoundFile addedFile = sfm.addSoundfile("E:\\Eclipse_Prj\\pSound\\data\\Adrenaline01.wav"); 
     SoundFile sf = sfm.getSoundfile(addedFile.getID()); 
     assertTrue(sf!=null); 
     System.out.println(sf.toString()); 

     sf = sfm.getSoundfileByName("E:\\Eclipse_Prj\\pSound\\data\\Adrenaline01.wav"); 
     assertTrue(sf!=null); 
     System.out.println(sf.toString()); 
    } catch (RapsManagerException e) { 
     fail(e.getMessage()); 
    } 
} 

@Test(expected=RapsManagerException.class) 
public void testGetWithInvalidId() { 
    SoundFileManager sfm = new SoundFileManager(); 

    sfm.getSoundfile(-100); 
} 

@Test(expected=RapsManagerException.class) 
public void testGetWithInvalidName() { 
    SoundFileManager sfm = new SoundFileManager(); 

    sfm.getSoundfileByName(new String()); 
} 
+0

जैसा कि मैंने उपर्युक्त कहा है, मुझे विचार पसंद है लेकिन मुझे एक चल रहे प्रोजेक्ट में जुनीट 4 पर स्विच करने का आगाह है। – InsertNickHere

+0

@InsertNickHere, आपको सामान्य सेटअप के साथ, अपने परीक्षण को 3 अलग-अलग तरीकों से तोड़ना चाहिए। फिर यदि आप वास्तव में अपवाद हैंडलिंग कोड को कम करना चाहते हैं (और आपके पास दिखाए गए जैसे बहुत सारे डुप्लिकेट कोड हैं) तो आप एक अलग विधि में कोशिश/पकड़ निकाल सकते हैं, और इंटरफ़ेस के माध्यम से परीक्षण करने के लिए वास्तविक विधि को पार कर सकते हैं (लेकिन यह वास्तव में आईएमएचओ से अधिक है, और यह आपके टेस्ट कोड को समझने में अधिक कठिन बनाता है)। –

12

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

Throwable caught = null; 
try { 
    somethingThatThrows(); 
} catch (Throwable t) { 
    caught = t; 
} 
assertNotNull(caught); 
assertSame(FooException.class, caught.getClass()); 

यदि आप इसके बजाय एनोटेशन का उपयोग कर सकते हैं, तो ऐसा करें क्योंकि यह बहुत स्पष्ट है। लेकिन यह हमेशा संभव नहीं होता है (उदाहरण के लिए, क्योंकि आप विधियों के अनुक्रम का परीक्षण कर रहे हैं या क्योंकि आप जुनीट 3 का उपयोग कर रहे हैं)।

+0

क्षमा करें, लेकिन मुझे आपकी तुलना में आपके संस्करण का कोई फायदा नहीं दिख रहा है। हो सकता है कि वहाँ JUnit3 साथ कोई भी है :( – InsertNickHere

+1

आप एक परीक्षण मामले में बहुत ज्यादा डाल रहे हैं। आप एक 'try' में बहुत ज्यादा डाल रहे हैं। आप बल्कि परीक्षण दावे विफल बनाने से मैनुअल पढ़ने के लिए गए संदेशों प्रिंट कर रहे बाहर!(आप अपने कोड में गैर पोर्टेबल पथ एम्बेड कर रहे हैं, लेकिन यह आपका व्यवसाय है ...) –

+0

पथ सिर्फ इस उदाहरण के लिए हैं, मैं यहां 100% मूल कोड पोस्ट नहीं करूंगा। लेकिन वैसे भी उस सलाह के लिए धन्यवाद। :) – InsertNickHere

2

सबसे संक्षिप्त वाक्य रचना catch-exception द्वारा प्रदान की जाती है:

public void testGet() { 
    SoundFileManager sfm = new SoundFileManager(); 
    ... // setup sound file manager 

    verifyException(sfm, RapsManagerException.class) 
     .getSoundfile(-100); 

    verifyException(sfm, RapsManagerException.class) 
     .getSoundfileByName(new String()); 
} 
0

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

static void <T extends Exception> expectException(Class<T> type, Runnable runnable) { 
    try { 
     runnable.run() 
    } catch (Exception ex) { 
     assertTrue(ex.getClass().equals(type)); 
     return; 
    } 
    assertTrue(false); 
} 

उपयोग:

@Test 
public void test() 
    MyClass foo = new MyClass(); 
    // other setup code here .... 
    expectException(MyException.class,() -> foo.bar()); 
} 
संबंधित मुद्दे