दिलचस्प पोस्ट
स्ट्रिंग के शुरू और अंत से ट्रिम रिक्त स्थान jQuery के यूआई accordion कि कई वर्गों खुला रहता है? एक पैनल में एक पृष्ठभूमि छवि जोड़ें स्टाइलशीट अद्यतन नहीं है एक छवि के रूप में एक नफंगे सरणी को सहेजना शब्दकोश में अधिकतम मूल्य के साथ कुंजी हो रही है? C99 stdint.h हैडर और एमएस विज़ुअल स्टूडियो wwinmain, यूनिकोड, और मिंगव सेवा का केवल एक उदाहरण बनाएं (एंड्रॉइड) सफ़ारी या UIWebView में HTTPS पर QuickTime फिल्में नहीं देख सकते जेपीए / हाइबरनेट स्टेटिक मेटामेडल विशेषताएँ नहीं आबादी – NullPointerException बाल विंडो से मूल विंडो को फिर से लोड करें एक चर से बैच निकालें पथ और फ़ाइल नाम बिना किसी लूप के कुंजी के द्वारा बहुआयामी सरणी का योग मान मिलन और एरो कोड

कैसे परीक्षण करने के लिए कि कोई अपवाद नहीं फेंक दिया जाता है?

मुझे पता है कि ऐसा करने का एक तरीका होगा:

@Test public void foo(){ try{ //execute code that you expect not to throw Exceptions. } catch(Exception e){ fail("Should not have thrown any exception"); } } 

क्या ऐसा करने का कोई भी क्लीनर तरीका है (शायद @Rule का उपयोग करते हैं @Rule ?)

Solutions Collecting From Web of "कैसे परीक्षण करने के लिए कि कोई अपवाद नहीं फेंक दिया जाता है?"

आप यह गलत तरीके से आ रहे हैं बस अपनी कार्यक्षमता का परीक्षण करें: यदि कोई अपवाद फेंका जाता है तो परीक्षा स्वचालित रूप से विफल हो जाएगी यदि कोई अपवाद नहीं फेंक दिया जाता है, तो आपके परीक्षण सभी हरे रंग की ओर बढ़ेंगे

मैंने देखा है कि इस प्रश्न को समय-समय पर ब्याज मिल जाता है इसलिए मैं थोड़ा विस्तार करूँगा

यूनिट परीक्षण की पृष्ठभूमि

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

या, जैसा कि यूनिट परीक्षण की कला, रॉय ओसहेरोव द्वारा 2 संस्करण , पृष्ठ 11 में परिभाषित किया गया है:

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

एहसास करना महत्वपूर्ण है कि काम की एक इकाई आमतौर पर केवल एक विधि नहीं है, लेकिन बहुत बुनियादी स्तर पर यह एक विधि है और इसके बाद इसे कार्य के अन्य इकाई द्वारा समझाया गया है।

यहां छवि विवरण दर्ज करें

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

कार्य की पहली इकाई को यह जांचना चाहिए कि मान्य और अमान्य इनपुट के मामले में वैध उपयोगकर्ता वापस किया जा रहा है या नहीं।
डेटास्त्रो द्वारा फेंक दिया जाने वाला कोई भी अपवाद यहां संभालना होगा: यदि कोई उपयोगकर्ता मौजूद नहीं है, तो एक ऐसा परीक्षण होना चाहिए जो दिखाता है कि अपवाद तब फेंका जाता है जब उपयोगकर्ता नहीं मिल सकता है। इसका एक नमूना @Test(expected = IllegalArgumentException.class) हो सकता है जो कि @Test(expected = IllegalArgumentException.class) टिप्पणी के साथ पकड़ा गया है।

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

एक परीक्षण 'वैध और दोषपूर्ण इनपुट हैंडलिंग

इस बिंदु पर यह स्पष्ट होना चाहिए कि हम इन अपवादों को कैसे संभालना चाहते हैं। इनपुट के 2 प्रकार हैं: मान्य इनपुट और दोषपूर्ण इनपुट (इनपुट सख्त अर्थ में मान्य है, लेकिन यह सही नहीं है)।

जब आप मान्य इनपुट के साथ काम करते हैं, तो आप जो भी परीक्षण लिखते हैं, वह अंतर्निहित प्रत्याशा निर्धारित कर रहे हैं, काम करेंगे।

ऐसी विधि कॉल इस तरह दिख सकती है: existingUserById_ShouldReturn_UserObject । यदि यह विधि विफल हो जाती है (उदाहरण: एक अपवाद फेंक जाता है) तो आप जानते हैं कि कुछ गलत हो गया है और आप खुदाई शुरू कर सकते हैं।

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

टी एल; डॉ

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

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

जावा 8 ने यह बहुत आसान बना दिया है, और Kotlin / Scala दोगुना इसलिए।

हम थोड़ा उपयोगिता वर्ग लिख सकते हैं

 class MyAssertions{ public static void assertDoesNotThrow(FailingRunnable action){ try{ action.run() } catch(Exception ex){ throw new Error("expected action not to throw, but it did!", ex) } } } @FunctionalInterface interface FailingRunnable { void run() throws Exception } 

और फिर आपका कोड बस हो जाता है:

 @Test public void foo(){ MyAssertions.assertDoesNotThrow(() -> { //execute code that you expect not to throw Exceptions. } } 

यदि आपके पास जावा -8 तक पहुंच नहीं है, तो मैं एक दर्दनाक पुरानी जावा सुविधा का उपयोग करूँगा: कोड कोड ब्लॉक और एक साधारण टिप्पणी

 //setup Component component = new Component(); //act configure(component); //assert /*assert does not throw*/{ component.doSomething(); } 

और अंत में, कॉटलिन के साथ, एक भाषा मैंने हाल ही में प्यार में गिर पड़ा:

 fun (() -> Any?).shouldNotThrow() = try { invoke() } catch (ex : Exception){ throw Error("expected not to throw!", ex) } @Test fun `when foo happens should not throw`(){ //... { /*code that shouldn't throw*/ }.shouldNotThrow() } 

यद्यपि बेला के लिए बहुत सारे कमरे हैं, ठीक से आप इसे कैसे व्यक्त करना चाहते हैं, मैं हमेशा धाराप्रवाह अभियुक्तों का प्रशंसक रहा हूं।


के बारे में

आप यह गलत तरीके से आ रहे हैं बस अपनी कार्यक्षमता का परीक्षण करें: यदि कोई अपवाद फेंका जाता है तो परीक्षा स्वचालित रूप से विफल हो जाएगी यदि कोई अपवाद नहीं फेंक दिया जाता है, तो आपके परीक्षण सभी हरे रंग की ओर बढ़ेंगे

यह सिद्धांत में सही है लेकिन निष्कर्ष में गलत है।

जावा नियंत्रण के प्रवाह के लिए अपवाद की अनुमति देता है यह JRE रनटाइम द्वारा एपीआई में ही किया जाता है जैसे कि Double.parseDouble माध्यम से एक NumberFormatException और Paths.get माध्यम से एक InvalidPathException

यह देखते हुए कि आपने एक घटक लिखा है, जो Double.ParseDouble स्ट्रिंग्स को Double.ParseDouble लिए मान्य करता है। Double.ParseDouble , शायद रेगेक्स का प्रयोग हो सकता है, हो सकता है एक लिखित पार्सर, या ऐसा कुछ जो कुछ अन्य डोमेन नियमों को एम्बेड करता है जो कि कुछ विशिष्ट की तुलना में कुछ की सीमा को प्रतिबंधित करता है, इस घटक का परीक्षण करने के लिए? मुझे लगता है कि एक स्पष्ट परीक्षण यह कहना होगा कि, जब परिणामी स्ट्रिंग पार्स हो जाती है, तो कोई अपवाद नहीं फेंका जाता है मैं उस परीक्षा को ऊपर बताए गए assertDoesNotThrow या /*comment*/{code} ब्लॉक का उपयोग करके assertDoesNotThrow । कुछ इस तरह

 @Test public void given_validator_accepts_string_result_should_be_interpretable_by_doubleParseDouble(){ //setup String input = "12.34E+26" //a string double with domain significance //act boolean isValid = component.validate(input) //assert -- using the library 'assertJ', my personal favourite assertThat(isValid).describedAs(input + " was considered valid by component").isTrue(); assertDoesNotThrow(() -> Double.parseDouble(input)); } 

मैं आपको Theories या Theories उपयोग से input पर इस परीक्षण को पैरामीटर करने के लिए प्रोत्साहित करता हूं ताकि आप अन्य निविष्टियों के लिए इस परीक्षा को और आसानी से दोबारा उपयोग कर सकें। वैकल्पिक रूप से, यदि आप विदेशी जाना चाहते हैं, तो आप एक परीक्षण-पीढ़ी के उपकरण (और इस ) के लिए जा सकते हैं। TestNG पैरामीटर वाले परीक्षणों के लिए बेहतर समर्थन है

क्या मुझे विशेष रूप से अप्रिय लगता है @Test(expectedException=IllegalArgumentException.class) का उपयोग करने की सिफारिश है @Test(expectedException=IllegalArgumentException.class) , यह अपवाद खतरनाक रूप से व्यापक है अगर आपका कोड इस तरह बदलता है कि परीक्षण के निर्माता के तहत घटक if(constructorArgument <= 0) throw IllegalArgumentException() , और आपका परीक्षण उस तर्क के लिए 0 की आपूर्ति कर रहा था क्योंकि यह सुविधाजनक था – और यह बहुत आम है, क्योंकि अच्छा जनरेटिंग टेस्ट डेटा एक आश्चर्यजनक मुश्किल समस्या है, तो आपका परीक्षण हरे-बार होगा, भले ही वह कुछ भी न जांच सके। ऐसे परीक्षण बेकार से भी बदतर है।

यदि आप अपने कोड में सभी त्रुटियों को पकड़ने के लिए पर्याप्त अशुभ हैं आप बेवकूफी कर सकते हैं

 class DumpTest { Exception ex; @Test public void testWhatEver() { try { thisShouldThroughError(); } catch (Exception e) { ex = e; } assertEquals(null,ex); } } 

मैंने सोनारक्यूब्स के नियम "स्क्विड: एस 2699" की वजह से इस पर ठोकर खाई: "इस परीक्षण के मामले में कम से कम एक तर्क जोड़ें।"

मेरे पास एक साधारण परीक्षण था जो केवल यह लक्ष्य था, कि यह बिना अपवाद के माध्यम से चला गया

इस सरल कोड की कल्पना करें:

 public class Printer { public static void printLine(final String line) { System.out.println(line); } } 

इस पद्धति का परीक्षण करने के लिए किस तरह का दावा जोड़ा जा सकता है? ज़रूर, आप इसे चारों ओर एक कोशिश पकड़ कर सकते हैं, लेकिन यह केवल कोड ब्लोट है

समाधान आपको स्वयं ही यूएनआईटी देता है

मामलों में कोई भी अपवाद नहीं फेंक दिया जाता है और आप इस व्यवहार को स्पष्ट रूप से स्पष्ट करना चाहते हैं, बस निम्नलिखित की उम्मीद की संभावना जोड़ना चाहते हैं:

 @Test(expected = Test.None.class /* no exception expected */) public void test_printLine() { Printer.printLine("line"); } 

टेस्ट.नोन। वर्ग अपेक्षित मान के लिए डिफ़ॉल्ट है

AssertJ धाराप्रवाह अभियुक्तों के साथ 3.7.0 :

 Assertions.assertThatCode(() -> toTest.method()) .doesNotThrowAnyException(); 

यदि आप यह परीक्षण करना चाहते हैं कि क्या आपका परीक्षण लक्ष्य अपवाद को खपता है बस इस परीक्षा को छोड़ दें (jock2 का उपयोग कर नकली सहयोगी):

 @Test public void consumesAndLogsExceptions() throws Exception { context.checking(new Expectations() { { oneOf(collaborator).doSth(); will(throwException(new NullPointerException())); } }); target.doSth(); } 

यह परीक्षण पारित होगा यदि आपका लक्ष्य फेंक दिया अपवाद का उपभोग करता है, अन्यथा परीक्षा विफल हो जाएगी

यदि आप अपने अपवाद खपत तर्क का परीक्षण करना चाहते हैं, तो चीज़ें अधिक जटिल हो जाती हैं मैं एक सहयोगी को खपत करने का सुझाव देता हूं जिसे मजाक किया जा सकता है। इसलिए परीक्षण हो सकता है:

 @Test public void consumesAndLogsExceptions() throws Exception { Exception e = new NullPointerException(); context.checking(new Expectations() { { allowing(collaborator).doSth(); will(throwException(e)); oneOf(consumer).consume(e); } }); target.doSth(); } 

लेकिन कभी-कभी यह अधिक-से-अधिक डिजाइन किया जाता है यदि आप इसे लॉग इन करना चाहते हैं। इस मामले में, यह आलेख ( http://java.dzone.com/articles/monitoring-declarative-transac , http://blog.novoj.net/2008/09/20/testing-aspect-pointcuts-is- वहां यदि आप इस मामले में टीडीडी पर जोर देते हैं, तो आप आसानी से मदद कर सकते हैं।

AssertNull का उपयोग करें (…)

 @Test public void foo() { try { //execute code that you expect not to throw Exceptions. } catch (Exception e){ assertNull(e); } } 

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

 @Test public void testMyCode() { try { runMyTestCode(); } catch (Throwable t) { throw new Error("fail!"); } } 

आप इसे @Rule का उपयोग कर कर सकते हैं और फिर विधि रिपोर्ट कॉल कर सकते हैंमिशिंगएक्सेप्शनहमसे संदेश दिखाया गया है: यह स्कला है, लेकिन यह आसानी से जावा में इसी तरह किया जा सकता है।

यहां छवि विवरण दर्ज करें

@ टेस्ट एनोटेशन अपेक्षित पैरामीटर प्रदान करता है

 @Test(expected=IllegalArgumentException.class) public void foo() { // Your test --> Will fail if not IlleArgumentException is thrown } 

आप अपेक्षा कर सकते हैं कि एक नियम बनाकर यह अपवाद फेंका नहीं गया है

 @Rule public ExpectedException expectedException = ExpectedException.none();