2012-01-10 20 views
7

में ब्लॉक जबकि मेरे कोड कवरेज की समीक्षा मैं ईकाई परीक्षण का एक बहुत अंत में ब्लॉक जो अंत में ब्लॉक में खुला InputStreams बंद करने की कोशिश की जाँच करने के लिए असफल देखा।इकाई परीक्षण अंत में जावा 6

एक उदाहरण अंश है:

try { 
     f = new BufferedInputStream(new FileInputStream(source)); 
     f.read(buffer); 
    } finally { 
     if (f != null) 
      try { 
       f.close(); 
      } catch (IOException ignored) { 
      } 
     } 
    } 

वहाँ अंदर अंत में JUnit4 का उपयोग कर ब्लॉक सब कुछ जांच करने के लिए कोई भी उचित समाधान है?

मुझे पता है कि 100% की एक कोड कवरेज प्राप्त करते समय मन में अधिकतम उत्पादकता रखने नहीं है। हालांकि ये लाल रेखाएं रिपोर्ट में एक eyecatcher की तरह हैं।

उत्तर

6

सबसे पहले में IOUtils.closeQuietly() का उपयोग कर, जो आपके अपरीक्षित कोड (और शायद दोहराव) कम हो जाएगा पर विचार करें। "सही" जिस तरह से एक और वर्ग में BufferedInputStream के निर्माण बाह्यरूप और नकली इंजेक्षन होगा। एक नकली होने के बाद आप यह सत्यापित कर सकते हैं कि उचित close() विधि लागू की गई थी या नहीं।

@JeffFoster के जवाब सुंदर मैं क्या मतलब के करीब है, फिर भी मैं विरासत से अधिक रचना की सिफारिश करेंगे (अधिक कोड की कीमत पर):

try { 
     f = fileSystem.open(source); 
     f.read(buffer); 
    } finally { 
     IOUtils.closeQuietly(f); 
    } 

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

interface FileSystem { 

    InputStream open(String file); 

} 

फ़ाइल खोलने externalizing का एक अन्य लाभ, संशोधित करने के लिए बस एक ही जगह नहीं है अगर आप एक बफरिंग हटाने या एन्क्रिप्शन जोड़ने का निर्णय लेते हैं।

कि इंटरफेस होने पर आप mocks (Mockito का प्रयोग करके) के साथ अपने परीक्षण कोड का दृष्टांत:

//given 
FileSystem fileSystemMock = mock(FileSystem.class); 
InputStream streamMock = mock(InputStream.class); 

given(fileSystemMock.open("file.txt")).willReturn(streamMock); 

//when 
//your code 

//then 
verify(streamMock).close(); 
+0

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

+0

धन्यवाद कि मैं वही था जो मैं देख रहा था :) धन्यवाद जेफ के लिए भी – fyr

5

आप इस

public class TestMe { 
    public void doSomething() { 
    try { 
     f = createStream() 
     f.read(buffer); 
    } finally { 
     if (f != null) 
     try { 
      f.close(); 
     } catch (IOException ignored) { } 
    } 
    } 

    public InputStream createStream() { 
     return new BufferedInputStream(new FileInputStream(source)); 
    } 
} 

की तरह कुछ करने के लिए कोड refactor सकता है एक छोटे से

public class TestMe { 
    public void doSomething() { 
    try { 
     f = new BufferedInputStream(new FileInputStream(source)); 
     f.read(buffer); 
    } finally { 
     if (f != null) 
     try { 
      f.close(); 
     } catch (IOException ignored) { } 
    } 
    } 
} 

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

public void TestSomething() { 
    InputStream foo = mock(InputStream.class); // mock object 
    TestMe testMe = new TestMe() { 
    @Override 
    public InputStream createStream() { 
      return foo; 
    } 
    } 

    testMe.something(); 

    verify(foo.close()); 
} 

चाहे यह इसके लायक है या नहीं, एक अलग सवाल है! अब यह मुश्किल हो जाता है

try { 
     f = new BufferedInputStream(new FileInputStream(source)); 
     f.read(buffer); 
    } finally { 
     IOUtils.closeQuietly(f); 
    } 

:

0

तुम एक मज़ाक उड़ाया BufferedInputStream इंजेक्षन चाहिए - या एक कारखाने के साथ बना सकते हैं - और नकली के close() विधि तो कहा जाता है जब फेंक एक IOException

साथ ही, मुझे लगता है कि अंत में ऊपर बंद नहीं होंगे जब तक आप वहाँ में कोई तर्क नहीं है।

0

मैं तुम्हें अपने आप से पूछना है कि क्या है कि वास्तव में परीक्षण के प्रयास के लायक है की जरूरत है। कुछ परीक्षण जंकियां ~ 100% परीक्षण कवरेज प्राप्त करने की कोशिश करने के कम रिटर्न को याद करते हैं।इस मामले में ऐसा लगता है कि प्रस्तावित समाधानों में से कुछ अधिक वास्तविक कोड के लिए जटिलता को "टेस्टेबल" बनाने के लिए जोड़ते हैं। मैं जटिल परीक्षण कोड के साथ ठीक हूं, लेकिन इसे "टेस्टेबल" बनाने के लिए वास्तविक कोड में जटिलता जोड़ना मुझे एक भयानक विचार के रूप में मारता है।