आप कैसे मानते हैं कि JUnit 4 परीक्षणों में एक निश्चित अपवाद को फेंक दिया गया है?


1998

मैं JUnit4 का मुहावरेदार तरीके से परीक्षण करने के लिए कैसे उपयोग कर सकता हूं कि कुछ कोड एक अपवाद फेंकता है?

जबकि मैं निश्चित रूप से ऐसा कुछ कर सकता हूं:

@Test
public void testFooThrowsIndexOutOfBoundsException() {
  boolean thrown = false;

  try {
    foo.doStuff();
  } catch (IndexOutOfBoundsException e) {
    thrown = true;
  }

  assertTrue(thrown);
}

मुझे याद है कि इस तरह की स्थितियों के लिए जुनेट का एक एनोटेशन या एक एसेरटाइक्सीज़ या ऐसा कुछ है जो बहुत कम कीचड़ और बहुत अधिक है।


21
किसी भी अन्य दृष्टिकोण के साथ समस्या लेकिन यह है कि अपवाद को फेंकने के बाद वे हमेशा परीक्षण समाप्त करते हैं। दूसरी ओर, मैं अक्सर org.mockito.Mockito.verifyयह सुनिश्चित करने के लिए विभिन्न मापदंडों के साथ कॉल करना चाहता हूं कि कुछ चीजें हुईं (जैसे कि एक लकड़हारा सेवा को सही मापदंडों के साथ बुलाया गया था) अपवाद को फेंकने से पहले।
जीरोऑन

5
आप यह देख सकते हैं कि JUnit wiki पृष्ठ github.com/junit-team/junit/wiki/Exception-testing
फोनिक्स

6
@ZeroOne - इसके लिए मेरे पास दो अलग-अलग परीक्षण होंगे- एक अपवाद के लिए और दूसरा आपके मॉक के साथ सहभागिता को सत्यापित करने के लिए।
tddmonkey

JUnit 5 के साथ ऐसा करने का एक तरीका है, मैंने नीचे अपना जवाब अपडेट किया है।
दिलिनी

जवाबों:


2360

यह JUnit संस्करण और आपके द्वारा उपयोग किए जाने वाले पुस्तकालयों पर निर्भर करता है।

इसका मूल उत्तर JUnit <= 4.12था:

@Test(expected = IndexOutOfBoundsException.class)
public void testIndexOutOfBoundsException() {

    ArrayList emptyList = new ArrayList();
    Object o = emptyList.get(0);

}

यद्यपि उत्तर https://stackoverflow.com/a/31826781/2986984 में JUnit <= 4.12 के अधिक विकल्प हैं।

संदर्भ:


66
यदि आप केवल अपने कोड में कहीं अपवाद की अपेक्षा करते हैं तो कोड का यह टुकड़ा काम नहीं करेगा, और इस तरह एक कंबल नहीं।
ओह चिन बून

4
@skaffman यह org.junit.experimental.theories के साथ काम नहीं करेगा। Theory द्वारा संचालित org.junit.experimental.theories.Theories
Artem Oboturov

74
रॉय ओशेरोव ने द आर्ट ऑफ़ यूनिट टेस्टिंग में इस तरह के एक्सेप्शन टेस्ट को हतोत्साहित किया , क्योंकि एक्सेप्शन टेस्ट के अंदर कहीं भी हो सकता है और न केवल टेस्ट के तहत यूनिट के अंदर।
केविन विटटेक

21
मैं @ कीव्यू / रॉय ओशेरोव से असहमत हूं। मेरे विचार में, परीक्षण व्यवहार के लिए होना चाहिए, कार्यान्वयन के लिए नहीं। यह परीक्षण करके कि एक विशिष्ट विधि एक त्रुटि फेंक सकती है, आप अपने परीक्षणों को सीधे कार्यान्वयन के लिए बांध रहे हैं। मैं तर्क दूंगा कि ऊपर दिखाए गए तरीके से परीक्षण अधिक मूल्यवान परीक्षण प्रदान करता है। मैं जो चेतावनी जोड़ूंगा वह यह है कि इस मामले में मैं एक कस्टम अपवाद के लिए परीक्षण करूंगा, ताकि मुझे पता चले कि मुझे वह अपवाद मिल रहा है जो मैं वास्तव में चाहता हूं।
निकबर

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

1315

संपादित करें: अब जब कि JUnit 5 और JUnit 4.13 जारी किए गए हैं, तो सबसे अच्छा विकल्प Assertions.assertThrows() (JUnit 5 के लिए) और Assert.assertThrows()(JUnit 4.13 के लिए ) उपयोग करना होगा । देखें मेरे अन्य जवाब जानकारी के लिए।

यदि आपने JUnit 5 में माइग्रेट नहीं किया है, लेकिन JUnit 4.7 का उपयोग कर सकते हैं, तो आप ExpectedExceptionनियम का उपयोग कर सकते हैं :

public class FooTest {
  @Rule
  public final ExpectedException exception = ExpectedException.none();

  @Test
  public void doStuffThrowsIndexOutOfBoundsException() {
    Foo foo = new Foo();

    exception.expect(IndexOutOfBoundsException.class);
    foo.doStuff();
  }
}

यह बहुत बेहतर है @Test(expected=IndexOutOfBoundsException.class)क्योंकि परीक्षण विफल हो जाएगा यदि IndexOutOfBoundsExceptionपहले फेंक दिया गया होfoo.doStuff()

देखें इस लेख जानकारी के लिए


14
@skaffman - यदि मैंने इसे सही ढंग से समझा है, तो यह अपवाद की तरह लगता है। एक्सपेक्ट केवल एक परीक्षण के भीतर लागू किया जा रहा है, न कि पूरी कक्षा के लिए।
बेकर

5
यदि हम जिस अपवाद को फेंकने की अपेक्षा करते हैं वह एक अपवाद है, तो क्या हमें इस स्थिति को दूसरे तरीके से फेंकना या आज़माना चाहिए या परीक्षण करना चाहिए?
मोहम्मद जाफ़र मशहदी

5
@MartinTrummer अपवाद फेंक दिए जाने के बाद से कोई कोड foo.doStuff () के बाद नहीं चलना चाहिए और विधि बाहर निकल जाती है। अपेक्षित अपवाद के बाद कोड होना (अंत में संसाधनों को बंद करने के अपवाद के साथ) वैसे भी अप्रभावी है क्योंकि अपवाद को फेंकने पर इसे कभी भी निष्पादित नहीं किया जाना चाहिए।
जेसन थॉम्पसन

9
यह सबसे अच्छा तरीका है। स्केफमैन के समाधान की तुलना में यहां दो फायदे हैं। सबसे पहले, ExpectedExceptionकक्षा में अपवाद के संदेश के मिलान के तरीके होते हैं, या यहां तक ​​कि अपने खुद के मिलान लिखने वाले भी अपवाद के वर्ग पर निर्भर करते हैं। दूसरे, आप अपनी उम्मीद को कोड की लाइन से पहले सेट कर सकते हैं जो आप अपवाद को फेंकने की अपेक्षा करते हैं - जिसका अर्थ है कि यदि कोड की गलत लाइन अपवाद को फेंकती है तो आपका परीक्षण विफल हो जाएगा; जबकि वहाँ कोई रास्ता नहीं है कि skaffman के समाधान के साथ है।
दाऊद इब्न करीम

5
@MJafarMash यदि आप जिस अपवाद को फेंकने की अपेक्षा करते हैं, उसकी जाँच की जाती है, तो आप उस अपवाद को परीक्षण विधि के थ्रो क्लॉज़ में जोड़ देंगे। आप किसी भी समय ऐसा कर रहे हैं जब आप एक विधि का परीक्षण कर रहे हैं, जो कि एक अपवाद को छोड़ने के लिए घोषित किया गया है, भले ही अपवाद विशेष परीक्षण के मामले में ट्रिगर न हुआ हो।
नाम्शुब्रिटर

471

अपेक्षित अपवाद का उपयोग करते समय सावधान रहें, क्योंकि यह केवल यह दावा करता है कि विधि ने उस अपवाद को फेंक दिया, न कि परीक्षण में कोड की एक विशेष पंक्ति

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

try {
    methodThatShouldThrow();
    fail( "My method didn't throw when I expected it to" );
} catch (MyException expectedException) {
}

निर्णय लागू करें।


95
शायद मैं पुराना स्कूल हूं लेकिन मैं अब भी इसे पसंद करता हूं। यह मुझे खुद अपवाद का परीक्षण करने के लिए एक जगह देता है: कभी-कभी मेरे पास कुछ मूल्यों के लिए गेटर्स के साथ अपवाद होते हैं, या मैं बस संदेश में एक विशेष मूल्य की तलाश कर सकता हूं (उदाहरण के लिए "xyz" संदेश में "अपरिचित कोड" xyz ') ")।
रोडनी गिजेल

3
मुझे लगता है कि NamshubWriter का दृष्टिकोण आपको दोनों दुनिया का सर्वश्रेष्ठ देता है।
एडी

4
ExpectedException का उपयोग करके आप इस अपवाद की तरह परीक्षण करने के लिए प्रति पद्धति N अपवाद कह सकते हैं। Dexect (IndexOutOfBoundsException.class); foo.doStuff1 (); exception.expect (IndexOutOfBoundsException.class); foo.doStuff2 (); exception.expect (IndexOutOfBoundsException.class); foo.doStuff3 ();
user1154664

10
@ user1154664 वास्तव में, आप नहीं कर सकते। ExpectedException का उपयोग करके आप केवल यह परीक्षण कर सकते हैं कि एक विधि एक अपवाद को फेंकती है, क्योंकि जब उस विधि को बुलाया जाता है, तो परीक्षण निष्पादित करना बंद कर देगा क्योंकि यह अपेक्षित अपवाद को फेंक देता है!
नामशूब्रिटर

2
आपका पहला वाक्य सिर्फ सच नहीं है। उपयोग करते समय ExpectedException, सामान्य बात यह है कि अपेक्षा को उस पंक्ति से ठीक पहले सेट करें जिसे आप अपवाद को फेंकने की अपेक्षा करते हैं। इस तरह, यदि एक पूर्व पंक्ति अपवाद फेंकता है, तो यह नियम को ट्रिगर नहीं करेगा, और परीक्षण विफल हो जाएगा।
दाऊद इब्न करीम

212

जैसा कि पहले कहा गया था, जुनीत में अपवादों से निपटने के कई तरीके हैं। लेकिन जावा 8 के साथ एक और भी है: लैम्ब्डा एक्सप्रेशंस का उपयोग करना। लैम्ब्डा एक्सप्रेशन के साथ हम इस तरह से एक सिंटैक्स प्राप्त कर सकते हैं:

@Test
public void verifiesTypeAndMessage() {
    assertThrown(new DummyService()::someMethod)
            .isInstanceOf(RuntimeException.class)
            .hasMessage("Runtime exception occurred")
            .hasMessageStartingWith("Runtime")
            .hasMessageEndingWith("occurred")
            .hasMessageContaining("exception")
            .hasNoCause();
}

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

यह अपेक्षाकृत सरल लेकिन शक्तिशाली तकनीक है।

इस तकनीक का वर्णन करने वाले इस ब्लॉग पोस्ट पर एक नज़र डालें: http://blog.codeleak.pl/2014/07/junit-testing-exception-with-java-8-and-lambda-expressions.html

स्रोत कोड यहां पाया जा सकता है: https://github.com/kolorobot/unit-testing-demo/tree/master/src/test/java/com/github/kolorobot/exception/ava8

प्रकटीकरण: मैं ब्लॉग और परियोजना का लेखक हूं।


2
मुझे यह समाधान पसंद है लेकिन क्या मैं इसे मावेन रेपो से डाउनलोड कर सकता हूं?
सेल्विन

@ इस विचार का एक कार्यान्वयन जो मावेन पर उपलब्ध है, वह
वाल्लाडो

6
@CristianoFont JUnit 4.13 के लिए इस API का एक सरल संस्करण स्लेट किया गया है। देखें github.com/junit-team/junit/commit/...
NamshubWriter

@RafalBorowiec तकनीकी रूप से, new DummyService()::someMethodएक है MethodHandle, लेकिन यह दृष्टिकोण लैम्ब्डा अभिव्यक्ति के साथ समान रूप से अच्छी तरह से काम करता है।
एंडी

@NamshubWriter, ऐसा लगता है कि जूनियर 4.13 को कनिष्ठ 5 के पक्ष में छोड़ दिया गया था: stackoverflow.com/questions/156503/…
वडज़िम

154

जूनट में, अपवाद का परीक्षण करने के चार तरीके हैं।

junit5.x

  • junit5.x के लिए, आप उपयोग कर सकते हैं assertThrowsनिम्नलिखित के रूप में

    @Test
    public void testFooThrowsIndexOutOfBoundsException() {
        Throwable exception = assertThrows(IndexOutOfBoundsException.class, () -> foo.doStuff());
        assertEquals("expected messages", exception.getMessage());
    }

junit4.x

  • junit4.x के लिए, परीक्षण घोषणा के वैकल्पिक 'अपेक्षित' विशेषता का उपयोग करें

    @Test(expected = IndexOutOfBoundsException.class)
    public void testFooThrowsIndexOutOfBoundsException() {
        foo.doStuff();
    }
  • junit4.x के लिए, ExpectedException नियम का उपयोग करें

    public class XxxTest {
        @Rule
        public ExpectedException thrown = ExpectedException.none();
    
        @Test
        public void testFooThrowsIndexOutOfBoundsException() {
            thrown.expect(IndexOutOfBoundsException.class)
            //you can test the exception message like
            thrown.expectMessage("expected messages");
            foo.doStuff();
        }
    }
  • आप कनिष्ठ 3 ढांचे के तहत व्यापक रूप से उपयोग किए जाने वाले क्लासिक प्रयास / कैच का उपयोग कर सकते हैं

    @Test
    public void testFooThrowsIndexOutOfBoundsException() {
        try {
            foo.doStuff();
            fail("expected exception was not occured.");
        } catch(IndexOutOfBoundsException e) {
            //if execution reaches here, 
            //it indicates this exception was occured.
            //so we need not handle it.
        }
    }
  • इसलिए

    • यदि आप 5 जून को पसंद करते हैं, तो आपको 1 को पसंद करना चाहिए
    • दूसरा तरीका तब इस्तेमाल किया जाता है जब आप केवल अपवाद के प्रकार का परीक्षण करना चाहते हैं
    • पहले और अंतिम दो का उपयोग तब किया जाता है जब आप परीक्षण अपवाद संदेश को आगे चाहते हैं
    • यदि आप junit 3 का उपयोग करते हैं, तो 4 वें को प्राथमिकता दी जाती है
  • अधिक जानकारी के लिए, आप इस दस्तावेज़ और विवरण के लिए junit5 उपयोगकर्ता गाइड पढ़ सकते हैं ।


6
मेरे लिए यह सबसे अच्छा जवाब है, यह बहुत स्पष्ट रूप से सभी तरीकों को शामिल करता है, धन्यवाद! व्यक्तिगत रूप से मैं पठनीयता के लिए Junit4 के साथ भी 3 विकल्प का उपयोग करना जारी रखता हूं, खाली कैच ब्लॉक से बचने के लिए आप थ्रोएबल और एसेर टाइप का ई भी पकड़ सकते हैं
निकोलस कॉर्नेट

क्या जाँच अपवाद की अपेक्षा ExpectedException का उपयोग करना संभव है?
miuser

यह सब शीर्ष तीन उत्तरों का संचय है। IMO, यह उत्तर भी पोस्ट नहीं किया जाना चाहिए अगर यह कुछ भी नया नहीं जोड़ रहा है। रेप के लिए बस (एक लोकप्रिय सवाल) का जवाब देना। बहुत बेकार है।
पॉल समसोथा

यकीन है, क्योंकि आप Trowableविधि से प्राप्त किसी भी प्रकार को पारित कर सकते हैं ExpectedException.expect। कृपया देखें कि यह हस्ताक्षर है । @ मिस्टर
वॉल्श

116

tl; डॉ

  • JDK8 के बाद: असाधारण व्यवहार को मुखर करने के लिए AssertJ या कस्टम लंबोदा का उपयोग करें ।

  • पूर्व JDK8: मैं पुराने अच्छा सिफारिश करेंगे try- catchब्लॉक। ( ब्लॉक से पहले एक विवरण जोड़ना न भूलेंfail()catch )

भले ही जून 4 या जुनीत 5।

लंबी कहानी

अपने आप को इसे स्वयं लिखना संभव है try- catchJUnit टूल को ब्लॉक करना या उपयोग करना ( @Test(expected = ...)या @Rule ExpectedExceptionJUnit रूल फीचर)।

लेकिन ये तरीके बहुत खूबसूरत नहीं हैं और अन्य उपकरणों के साथ अच्छी तरह से पठनीय समझदारी नहीं है । इसके अलावा, JUnit टूलींग में कुछ नुकसान हैं।

  1. try- catchब्लॉक आप परीक्षण किया व्यवहार के ब्लॉक लिखने और कैच ब्लॉक में जोर लिखने के लिए है, यह ठीक है, लेकिन कई खोज हो सकता है कि इस शैली बीच में आता है एक परीक्षण के पढ़ने प्रवाह। इसके अलावा, आपको ब्लॉक Assert.failके अंत में लिखने की जरूरत है try। अन्यथा, परीक्षण के एक पक्ष को याद कर सकते हैं; पीएमडी , फाइंडबग्स या सोनार ऐसे मुद्दों को जगह देंगे।

  2. यह @Test(expected = ...)सुविधा दिलचस्प है क्योंकि आप कम कोड लिख सकते हैं और फिर इस परीक्षा को लिखने से कोडिंग त्रुटियों का खतरा कम होता है। लेकिन कुछ क्षेत्रों में इस दृष्टिकोण का अभाव है।

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

      @Test(expected = WantedException.class)
      public void call2_should_throw_a_WantedException__not_call1() {
          // init tested
          tested.call1(); // may throw a WantedException
      
          // call to be actually tested
          tested.call2(); // the call that is supposed to raise an exception
      }
  3. ExpectedExceptionनियम भी पिछले चेतावनियां को ठीक करने का प्रयास है, लेकिन यह एक के रूप में यह एक उम्मीद शैली का उपयोग करता है का उपयोग करने के अजीब सा लगता है, EasyMock उन बहुत अच्छी तरह से इस शैली पता है। यह कुछ के लिए सुविधाजनक हो सकता है, लेकिन यदि आप व्यवहार चालित विकास (BDD) या व्यवस्था अधिनियम Assert (AAA) सिद्धांतों का पालन करते हैं, तो ExpectedExceptionनियम उन लेखन शैली में फिट नहीं होगा। इसके अलावा यह उसी तरह से समस्या से ग्रस्त हो सकता है @Test, जिस पर आप अपेक्षा रखते हैं।

    @Rule ExpectedException thrown = ExpectedException.none()
    
    @Test
    public void call2_should_throw_a_WantedException__not_call1() {
        // expectations
        thrown.expect(WantedException.class);
        thrown.expectMessage("boom");
    
        // init tested
        tested.call1(); // may throw a WantedException
    
        // call to be actually tested
        tested.call2(); // the call that is supposed to raise an exception
    }

    यहां तक ​​कि अपेक्षित अपवाद को परीक्षण के बयान से पहले रखा गया है, यह आपके पढ़ने के प्रवाह को तोड़ता है अगर परीक्षण बीडीडी या एएए का पालन करते हैं।

    इसके अलावा, लेखक के जेयूनिट पर इस टिप्पणी के मुद्दे को देखें ExpectedExceptionJUnit 4.13-beta-2 भी इस तंत्र को चित्रित करता है:

    पुल अनुरोध # 1519 : अपेक्षित प्रत्याशा

    विधि Assert.assertThrows अपवादों को सत्यापित करने के लिए एक अच्छा तरीका प्रदान करता है। इसके अतिरिक्त, ExpectedException का उपयोग त्रुटि-प्रवण है जब TestWatcher जैसे अन्य नियमों के साथ उपयोग किया जाता है क्योंकि नियमों का क्रम उस मामले में महत्वपूर्ण है।

इसलिए इन उपरोक्त विकल्पों में उनके सभी भार हैं, और स्पष्ट रूप से कोडर त्रुटियों के लिए प्रतिरक्षा नहीं है।

  1. इस परियोजना के बारे में मुझे पता है कि यह जवाब देने के बाद मुझे पता चला कि यह आशाजनक है, यह कैच-अपवाद है

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

    होम पेज से लिया गया एक तेज़ उदाहरण:

    // given: an empty list
    List myList = new ArrayList();
    
    // when: we try to get the first element of the list
    when(myList).get(1);
    
    // then: we expect an IndexOutOfBoundsException
    then(caughtException())
            .isInstanceOf(IndexOutOfBoundsException.class)
            .hasMessage("Index: 1, Size: 0") 
            .hasNoCause();

    जैसा कि आप देख सकते हैं कि कोड वास्तव में सीधा है, आप एक विशिष्ट लाइन पर अपवाद को पकड़ते हैं, thenएपीआई एक उपनाम है जो AssertJ APIs (उपयोग करने के समान assertThat(ex).hasNoCause()...) का उपयोग करेगा । कुछ समय में यह परियोजना एस्टरज के पूर्वज-पूर्वज पर निर्भर थीसंपादित करें: ऐसा लगता है कि परियोजना जावा 8 लैम्ब्डा के समर्थन को बढ़ा रही है।

    वर्तमान में, इस पुस्तकालय में दो कमियाँ हैं:

    • इस लेखन के समय, यह कहना उल्लेखनीय है कि यह पुस्तकालय मॉकिटो 1.x पर आधारित है क्योंकि यह दृश्य के पीछे परीक्षण की गई वस्तु का नकली बनाता है। जैसा कि मॉकिटो अभी भी अपडेट नहीं है, यह लाइब्रेरी अंतिम कक्षाओं या अंतिम विधियों के साथ काम नहीं कर सकती है । और यहां तक ​​कि अगर यह मौजूदा संस्करण में मॉकिटो 2 पर आधारित था, तो इसके लिए एक वैश्विक मॉक मेकर ( inline-mock-maker) घोषित करने की आवश्यकता होगी , कुछ ऐसा जो आप नहीं चाहते हैं, क्योंकि इस मॉक मेकर में अलग-अलग कमियां हैं जो नियमित मॉक निर्माता हैं।

    • इसके लिए एक और परीक्षण निर्भरता की आवश्यकता है।

    पुस्तकालय लैंबडास का समर्थन करने के बाद ये मुद्दे लागू नहीं होंगे। हालाँकि, कार्यक्षमता को AssertJ टूलसेट द्वारा डुप्लिकेट किया जाएगा।

    सभी को ध्यान में रखते हुए यदि आप कैच-अपवाद टूल का उपयोग नहीं करना चाहते हैं, तो मैं try- catchब्लॉक के पुराने अच्छे तरीके की सिफारिश करूंगा , कम से कम JDK7 तक। और JDK 8 उपयोगकर्ताओं के लिए आप AssertJ का उपयोग करना पसंद कर सकते हैं क्योंकि यह केवल अपवादों को मुखर करने से अधिक हो सकता है।

  2. JDK8 के साथ, लैम्ब्डा परीक्षण दृश्य में प्रवेश करते हैं, और वे असाधारण व्यवहार को मुखर करने के लिए एक दिलचस्प तरीका साबित हुए हैं। AsserJ असाधारण व्यवहार को मुखर करने के लिए एक अच्छा धाराप्रवाह एपीआई प्रदान करने के लिए अद्यतन किया गया है।

    और AssertJ के साथ एक नमूना परीक्षण :

    @Test
    public void test_exception_approach_1() {
        ...
        assertThatExceptionOfType(IOException.class)
                .isThrownBy(() -> someBadIOOperation())
                .withMessage("boom!"); 
    }
    
    @Test
    public void test_exception_approach_2() {
        ...
        assertThatThrownBy(() -> someBadIOOperation())
                .isInstanceOf(Exception.class)
                .hasMessageContaining("boom");
    }
    
    @Test
    public void test_exception_approach_3() {
        ...
        // when
        Throwable thrown = catchThrowable(() -> someBadIOOperation());
    
        // then
        assertThat(thrown).isInstanceOf(Exception.class)
                          .hasMessageContaining("boom");
    }
  3. JUnit 5 के लगभग पूर्ण पुनर्लेखन के साथ, अभिकथनों में थोड़ा सुधार किया गया है , वे सही तरीके से अपवाद करने के लिए बॉक्स के बाहर के रूप में दिलचस्प साबित हो सकते हैं। लेकिन वास्तव में मुखर एपीआई अभी भी थोड़ा गरीब है, बाहर कुछ भी नहीं है assertThrows

    @Test
    @DisplayName("throws EmptyStackException when peeked")
    void throwsExceptionWhenPeeked() {
        Throwable t = assertThrows(EmptyStackException.class, () -> stack.peek());
    
        Assertions.assertEquals("...", t.getMessage());
    }

    जैसा कि आपने देखा assertEqualsकि अभी भी लौट रहा हैvoid , और जैसे कि AssertJ जैसे जोर देने की अनुमति नहीं देता है।

    यदि आपको नाम क्लैश याद है Matcherया Assert, तो उसी क्लैश को पूरा करने के लिए तैयार रहें Assertions

मैं यह निष्कर्ष निकालना चाहता हूं कि आज (2017-03-03) AssertJ की उपयोग में आसानी, खोज योग्य एपीआई, विकास की तीव्र गति और एक वास्तविक परीक्षण निर्भरता के रूप में JDK8 के साथ सबसे अच्छा समाधान है, भले ही परीक्षण रूपरेखा (JUKit) या नहीं), पूर्व JDKs पर निर्भर होना चाहिए try-catch ब्लॉक भले ही वे भद्दा महसूस करते हैं।

यह उत्तर एक अन्य प्रश्न से कॉपी किया गया है जिसमें समान दृश्यता नहीं है, मैं एक ही लेखक हूं।


1
Org.junit.jupiter: junit-jupiter-engine: 5.0.0-RC2 निर्भरता (पहले से मौजूद जूनियर के अलावा: junit: 4.12) को जोड़ने के लिए उपयोग करने में सक्षम होने के लिए संभवत: पसंदीदा समाधान नहीं है, लेकिन इसका कोई कारण नहीं था मेरे लिए समस्या है।
ऐर

मैं ExpectedException नियम का उपयोग करने का प्रशंसक हूं, लेकिन इसने मुझे हमेशा परेशान किया कि यह AAA से टूट जाता है। आपने सभी अलग-अलग तरीकों का वर्णन करने के लिए एक उत्कृष्ट लेख लिखा है और आपने निश्चित रूप से मुझे AssertJ :-) का प्रयास करने के लिए प्रोत्साहित किया है! धन्यवाद!
पिम हजेब्रोक

@PimHazebroek धन्यवाद AssertJ API काफी समृद्ध है। मेरी राय में बेहतर है कि ज्यूनिट बॉक्स से बाहर क्या प्रस्तावित करता है।
ब्राइस

64

अब जब JUnit 5 और JUnit 4.13 जारी कर दिए गए हैं, तो सबसे अच्छा विकल्प Assertions.assertThrows() (JUnit 5 के लिए) और Assert.assertThrows()(JUnit 4.13 के लिए ) उपयोग करना होगा । जून 5 उपयोगकर्ता गाइड देखें ।

यहाँ एक उदाहरण है कि एक अपवाद की पुष्टि की जाती है, और सत्य का उपयोग अपवाद संदेश पर जोर देने के लिए किया जाता है:

public class FooTest {
  @Test
  public void doStuffThrowsIndexOutOfBoundsException() {
    Foo foo = new Foo();

    IndexOutOfBoundsException e = assertThrows(
        IndexOutOfBoundsException.class, foo::doStuff);

    assertThat(e).hasMessageThat().contains("woops!");
  }
}

अन्य उत्तरों में दृष्टिकोण के फायदे हैं:

  1. JUnit में बनाया गया
  2. यदि लैम्ब्डा में कोड एक अपवाद नहीं फेंकता है, और एक स्टैकट्रेस यदि यह एक अलग अपवाद फेंकता है तो आपको एक उपयोगी अपवाद संदेश मिलता है
  3. संक्षिप्त
  4. अपने परीक्षणों को व्यवस्था-अधिनियम-अभिकारक का पालन करने की अनुमति देता है
  5. आप अपवाद को फेंकने की उम्मीद कर रहे हैं कि आप किस कोड को इंगित कर सकते हैं
  6. आपको throwsक्लॉज में अपेक्षित अपवाद को सूचीबद्ध करने की आवश्यकता नहीं है
  7. पकड़े गए अपवाद के बारे में दावे करने के लिए आप अपनी पसंद के दावे के ढांचे का उपयोग कर सकते हैं

org.junit AssertJUnit 4.13 में एक समान विधि जोड़ी जाएगी ।


यह दृष्टिकोण साफ है, लेकिन मैं यह नहीं देखता कि यह हमारे परीक्षण को "अरेंज-एक्ट-एस्टर" का पालन करने की अनुमति कैसे देता है, क्योंकि हमें "एक्टर" भाग को "एस्टरथ्रो" में लपेटना है, जो एक मुखर है।
घड़ी की कल

@ क्लॉकवर्क लैम्ब्डा "एक्ट" है। अरेंज-एक्ट-एस्टर का लक्ष्य कोड को साफ और सरल बनाना है (और इसलिए समझना और बनाए रखना आसान है)। जैसा कि आपने कहा, यह दृष्टिकोण साफ है।
नाम्शुब्रिटर

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

यह दावा करने के लिए हर परीक्षा में अधिक कोड की आवश्यकता होगी। यह अधिक कोड है और त्रुटि-प्रवण होगा।
नामशूब्रिटर

42

इसके बारे में कैसे: एक बहुत ही सामान्य अपवाद को पकड़ो, सुनिश्चित करें कि यह इसे कैच ब्लॉक से बाहर कर देता है, फिर यह दावा करें कि अपवाद का वर्ग वह है जो आप इसके होने की उम्मीद करते हैं। यदि यह अपवाद विफल हो जाता है तो a) अपवाद गलत प्रकार का है (जैसे। यदि आपको इसके बजाय एक नल सूचक मिला है) और b) अपवाद कभी नहीं फेंका गया था।

public void testFooThrowsIndexOutOfBoundsException() {
  Throwable e = null;

  try {
    foo.doStuff();
  } catch (Throwable ex) {
    e = ex;
  }

  assertTrue(e instanceof IndexOutOfBoundsException);
}

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

इसे थोड़ा बदलकर बेहतर किया जा सकता है कि आप आखिर में कैसे जोर देते हैं। assertEquals(ExpectedException.class, e.getClass())परीक्षण विफल होने पर आपको अपेक्षित और वास्तविक मूल्य दिखाएंगे।
साइफ्रे

37

BDD स्टाइल सॉल्यूशन: JUnit 4 + कैच एक्सेप्शन + AssertJ

import static com.googlecode.catchexception.apis.BDDCatchException.*;

@Test
public void testFooThrowsIndexOutOfBoundsException() {

    when(() -> foo.doStuff());

    then(caughtException()).isInstanceOf(IndexOutOfBoundsException.class);

}

निर्भरता

eu.codearte.catch-exception:catch-exception:2.0

36

ज्यूरिट के साथ प्रयोग किया जा सकता है, जो एक जोर का उपयोग करना :

import static org.assertj.core.api.Assertions.*;

@Test
public void testFooThrowsIndexOutOfBoundsException() {
  Foo foo = new Foo();

  assertThatThrownBy(() -> foo.doStuff())
        .isInstanceOf(IndexOutOfBoundsException.class);
}

यह बेहतर है @Test(expected=IndexOutOfBoundsException.class)क्योंकि यह परीक्षण में अपेक्षित लाइन की गारंटी देता है अपवाद को फेंक दिया और आपको अपवाद के बारे में अधिक जानकारी की जांच करने देता है, जैसे संदेश, आसान:

assertThatThrownBy(() ->
       {
         throw new Exception("boom!");
       })
    .isInstanceOf(Exception.class)
    .hasMessageContaining("boom");

मावेन / स्नातक निर्देश यहाँ।


सबसे संक्षिप्त तरीका है और कोई भी इसकी सराहना नहीं करता है, अजीब है .. मुझे केवल एसरजेज लाइब्रेरी के साथ एक समस्या है, यह जोर-जोर से जूनियर के साथ नाम-वार का सामना करता है। assertJ के बारे में और अधिक जोर: JUnit: जावा 8 और AssertJ 3.0.0 के साथ परीक्षण अपवाद ~ Codeleak.pl
ycomp

@ycomp वैसे तो यह बहुत पुराने प्रश्न पर एक नया उत्तर है, इसलिए स्कोर अंतर भ्रामक है।
पश्चिम

शायद यह सबसे अच्छा समाधान है अगर कोई जावा 8 और एसेटर्ज का उपयोग कर सकता है!
पियरे हेनरी

@ मुझे लगता है कि यह नाम संघर्ष डिज़ाइन द्वारा हो सकता है: AssertJ लाइब्रेरी इसलिए दृढ़ता से प्रोत्साहित करती है कि आप JUnit assertThat, हमेशा AssertJ एक का उपयोग न करें । इसके अलावा JUnit विधि केवल एक "नियमित" प्रकार लौटाती है, जबकि AssertJ विधि एक AbstractAssertउपवर्ग लौटाती है ... उपरोक्त तरीकों की स्ट्रिंग की अनुमति देता है (या इसके लिए तकनीकी शब्द जो भी हो ...)।
माइक कृंतक

@ वेस्टन वास्तव में मैंने अपनी तकनीक का उपयोग AssertJ 2.0.0 में किया है। उन्नयन के लिए कोई बहाना नहीं, कोई संदेह नहीं है, लेकिन यद्यपि आप जानना चाहते हैं।
माइक कृंतक

33

उसी समस्या को हल करने के लिए मैंने एक छोटी परियोजना स्थापित की: बनाई http://code.google.com/p/catch-exception/

इस छोटे सहायक का उपयोग कर आप लिखेंगे

verifyException(foo, IndexOutOfBoundsException.class).doStuff();

यह JUnit 4.7 के ExpectedException नियम की तुलना में कम क्रिया है। स्कैफ़मैन द्वारा प्रदान किए गए समाधान की तुलना में, आप निर्दिष्ट कर सकते हैं कि आप किस कोड के अपवाद की अपेक्षा करते हैं। आशा है कि ये आपकी मदद करेगा।


मैंने ऐसा कुछ करने के बारे में भी सोचा था, लेकिन अंततः यह पता चला कि ExpectedException की असली शक्ति यह है कि आप न केवल अपेक्षित अपवाद निर्दिष्ट कर सकते हैं, बल्कि आप अपवाद के कुछ गुणों जैसे कि अपेक्षित कारण या अपेक्षित संदेश भी निर्दिष्ट कर सकते हैं।
जेसन थॉम्पसन

मेरा अनुमान है कि इस समाधान में मोक्स जैसी कुछ कमियां हैं? उदाहरण के लिए, यदि fooहै finalयह असफल हो जायेगी क्योंकि आप प्रॉक्सी नहीं कर सकते foo?
टॉम

टॉम, अगर doStuff () एक इंटरफ़ेस का हिस्सा है जो प्रॉक्सी दृष्टिकोण काम करेगा। अन्यथा यह दृष्टिकोण विफल हो जाएगा, आप सही हैं।
rwitzel

31

अपडेट: JUnit5 में अपवाद परीक्षण के लिए सुधार है:assertThrows :।

निम्नलिखित उदाहरण से है: जून 5 उपयोगकर्ता गाइड

 @Test
void exceptionTesting() {
    Throwable exception = assertThrows(IllegalArgumentException.class, () -> 
    {
        throw new IllegalArgumentException("a message");
    });
    assertEquals("a message", exception.getMessage());
}

मूल उत्तर JUnit 4 का उपयोग कर।

परीक्षण करने के कई तरीके हैं कि एक अपवाद फेंक दिया गया है। मैंने अपनी पोस्ट में नीचे दिए गए विकल्पों पर भी चर्चा की है JUnit के साथ महान इकाई परीक्षण कैसे लिखें

expectedपैरामीटर सेट करें @Test(expected = FileNotFoundException.class)

@Test(expected = FileNotFoundException.class) 
public void testReadFile() { 
    myClass.readFile("test.txt");
}

का उपयोग करते हुए try catch

public void testReadFile() { 
    try {
        myClass.readFile("test.txt");
        fail("Expected a FileNotFoundException to be thrown");
    } catch (FileNotFoundException e) {
        assertThat(e.getMessage(), is("The file test.txt does not exist!"));
    }

}

ExpectedExceptionनियम से परीक्षण ।

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

@Test
public void testReadFile() throws FileNotFoundException {

    thrown.expect(FileNotFoundException.class);
    thrown.expectMessage(startsWith("The file test.txt"));
    myClass.readFile("test.txt");
}

आप अपवाद परीक्षण के लिए JUnit4 विकि में अपवाद परीक्षण के बारे में अधिक पढ़ सकते हैं और bad.robot - अपवाद JUnit नियम की अपेक्षा कर सकते हैं


22

आप यह भी कर सकते हैं:

@Test
public void testFooThrowsIndexOutOfBoundsException() {
    try {
        foo.doStuff();
        assert false;
    } catch (IndexOutOfBoundsException e) {
        assert true;
    }
}

12
JUnit परीक्षणों में, उपयोग करना बेहतर है Assert.fail(), न कि assertआपके परीक्षण ऐसे वातावरण में चलते हैं जहाँ दावे सक्षम नहीं हैं।
नामशूब्रिटर

14

IMHO, JUnit में अपवादों की जांच करने का सबसे अच्छा तरीका ट्राइ / कैच / असफल / मुखर पैटर्न है:

// this try block should be as small as possible,
// as you want to make sure you only catch exceptions from your code
try {
    sut.doThing();
    fail(); // fail if this does not throw any exception
} catch(MyException e) { // only catch the exception you expect,
                         // otherwise you may catch an exception for a dependency unexpectedly
    // a strong assertion on the message, 
    // in case the exception comes from anywhere an unexpected line of code,
    // especially important if your checking IllegalArgumentExceptions
    assertEquals("the message I get", e.getMessage()); 
}

assertTrueकुछ लोगों के लिए थोड़ा मजबूत हो सकता है, तो assertThat(e.getMessage(), containsString("the message");बेहतर हो सकता है।


13

JUnit 5 समाधान

@Test
void testFooThrowsIndexOutOfBoundsException() {    
  Throwable exception = expectThrows( IndexOutOfBoundsException.class, foo::doStuff );

  assertEquals( "some message", exception.getMessage() );
}

JUnit 5 के बारे में अधिक जानकारी http://junit.org/junit5/docs/current/user-guide/#writing-tests-assertions पर


expectThrows()एक भाग TestNG है, न कि JUnit
Lu55

13

Junit 4 के लिए सबसे लचीला और सुरुचिपूर्ण उत्तर मुझे Mkyong ब्लॉग में मिला । इसमें एनोटेशन try/catchका उपयोग करने का लचीलापन है @Rule। मुझे यह दृष्टिकोण पसंद है क्योंकि आप एक अनुकूलित अपवाद की विशिष्ट विशेषताओं को पढ़ सकते हैं।

package com.mkyong;

import com.mkyong.examples.CustomerService;
import com.mkyong.examples.exception.NameNotFoundException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.hasProperty;

public class Exception3Test {

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

    @Test
    public void testNameNotFoundException() throws NameNotFoundException {

        //test specific type of exception
        thrown.expect(NameNotFoundException.class);

        //test message
        thrown.expectMessage(is("Name is empty!"));

        //test detail
        thrown.expect(hasProperty("errCode"));  //make sure getters n setters are defined.
        thrown.expect(hasProperty("errCode", is(666)));

        CustomerService cust = new CustomerService();
        cust.findByName("");

    }

}

12

मैंने यहां कई तरीके आजमाए, लेकिन वे या तो जटिल थे या मेरी आवश्यकताओं को पूरा नहीं करते थे। वास्तव में, कोई सहायक विधि को बहुत सरलता से लिख सकता है:

public class ExceptionAssertions {
    public static void assertException(BlastContainer blastContainer ) {
        boolean caughtException = false;
        try {
            blastContainer.test();
        } catch( Exception e ) {
            caughtException = true;
        }
        if( !caughtException ) {
            throw new AssertionFailedError("exception expected to be thrown, but was not");
        }
    }
    public static interface BlastContainer {
        public void test() throws Exception;
    }
}

इसे इस तरह उपयोग करें:

assertException(new BlastContainer() {
    @Override
    public void test() throws Exception {
        doSomethingThatShouldExceptHere();
    }
});

शून्य निर्भरता: मॉकिटो के लिए कोई ज़रूरत नहीं, कोई मोरम की ज़रूरत नहीं; और अंतिम कक्षाओं के साथ ठीक काम करता है।


दिलचस्प है, लेकिन एएए (एक्ट अरेंजमेंट) के लिए फिट नहीं है, जहां आप एक्ट और एस्टर के कदम को वास्तव में अलग-अलग चरणों में करना चाहते हैं।
bln-tom

1
@ bln-टॉम तकनीकी रूप से यह दो अलग-अलग चरण हैं, वे सिर्फ उसी क्रम में नहीं हैं। ; पी
ट्रेकज़ाज़

10

जावा 8 समाधान

यदि आप एक समाधान चाहते हैं जो:

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

यहाँ एक उपयोगिता कार्य है जो मैंने लिखा है:

public final <T extends Throwable> T expectException( Class<T> exceptionClass, Runnable runnable )
{
    try
    {
        runnable.run();
    }
    catch( Throwable throwable )
    {
        if( throwable instanceof AssertionError && throwable.getCause() != null )
            throwable = throwable.getCause(); //allows "assert x != null : new IllegalArgumentException();"
        assert exceptionClass.isInstance( throwable ) : throwable; //exception of the wrong kind was thrown.
        assert throwable.getClass() == exceptionClass : throwable; //exception thrown was a subclass, but not the exact class, expected.
        @SuppressWarnings( "unchecked" )
        T result = (T)throwable;
        return result;
    }
    assert false; //expected exception was not thrown.
    return null; //to keep the compiler happy.
}

( मेरे ब्लॉग से लिया गया )

इसे निम्नानुसार उपयोग करें:

@Test
public void testThrows()
{
    RuntimeException e = expectException( RuntimeException.class, () -> 
        {
            throw new RuntimeException( "fail!" );
        } );
    assert e.getMessage().equals( "fail!" );
}


8

मेरे मामले में मुझे हमेशा db से RuntimeException मिलती है, लेकिन संदेश अलग-अलग होते हैं। और अपवाद को क्रमशः संभालने की आवश्यकता है। यहाँ है कि मैंने इसे कैसे परीक्षण किया:

@Test
public void testThrowsExceptionWhenWrongSku() {

    // Given
    String articleSimpleSku = "999-999";
    int amountOfTransactions = 1;
    Exception exception = null;

    // When
    try {
        createNInboundTransactionsForSku(amountOfTransactions, articleSimpleSku);
    } catch (RuntimeException e) {
        exception = e;
    }

    // Then
    shouldValidateThrowsExceptionWithMessage(exception, MESSAGE_NON_EXISTENT_SKU);
}

private void shouldValidateThrowsExceptionWithMessage(final Exception e, final String message) {
    assertNotNull(e);
    assertTrue(e.getMessage().contains(message));
}

1
रेखा के साथ } catch (, आपको सम्मिलित करना चाहिएfail("no exception thrown");
डैनियल एल्डर

6

बस एक ऐसा मिलान बनाएं जिसे बंद और चालू किया जा सके, जैसे:

public class ExceptionMatcher extends BaseMatcher<Throwable> {
    private boolean active = true;
    private Class<? extends Throwable> throwable;

    public ExceptionMatcher(Class<? extends Throwable> throwable) {
        this.throwable = throwable;
    }

    public void on() {
        this.active = true;
    }

    public void off() {
        this.active = false;
    }

    @Override
    public boolean matches(Object object) {
        return active && throwable.isAssignableFrom(object.getClass());
    }

    @Override
    public void describeTo(Description description) {
        description.appendText("not the covered exception type");
    }
}

इसके प्रयेाग के लिए:

जोड़ें public ExpectedException exception = ExpectedException.none();, फिर:

ExceptionMatcher exMatch = new ExceptionMatcher(MyException.class);
exception.expect(exMatch);
someObject.somethingThatThrowsMyException();
exMatch.off();

6

JUnit 4 में या बाद में आप निम्नानुसार परीक्षण कर सकते हैं

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


यह बहुत सी सुविधाएँ प्रदान करता है जिनका उपयोग हमारे JUnit परीक्षणों को बेहतर बनाने के लिए किया जा सकता है।
यदि आप नीचे दिए गए उदाहरण को देखते हैं तो मैं अपवाद पर 3 चीजों का परीक्षण कर रहा हूं।

  1. अपवाद का प्रकार
  2. अपवाद संदेश
  3. अपवाद का कारण


public class MyTest {

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

    ClassUnderTest classUnderTest;

    @Before
    public void setUp() throws Exception {
        classUnderTest = new ClassUnderTest();
    }

    @Test
    public void testAppleisSweetAndRed() throws Exception {

        exceptions.expect(Exception.class);
        exceptions.expectMessage("this is the exception message");
        exceptions.expectCause(Matchers.<Throwable>equalTo(exceptionCause));

        classUnderTest.methodUnderTest("param1", "param2");
    }

}

6

हम एक अपवाद का उपयोग कर सकते हैं जो एक अपवाद को वापस करने के तरीके के बाद एक असफलता का उपयोग कर सकते हैं:

try{
   methodThatThrowMyException();
   Assert.fail("MyException is not thrown !");
} catch (final Exception exception) {
   // Verify if the thrown exception is instance of MyException, otherwise throws an assert failure
   assertTrue(exception instanceof MyException, "An exception other than MyException is thrown !");
   // In case of verifying the error message
   MyException myException = (MyException) exception;
   assertEquals("EXPECTED ERROR MESSAGE", myException.getMessage());
}

3
दूसरा catchस्टैक ट्रेस निगल जाएगा यदि कुछ अन्य अपवाद को फेंक दिया जाए, तो उपयोगी जानकारी खोना
NamshubWriter

5

इसके अलावा नामशूद्र ने जो कहा है, वह सुनिश्चित करें कि:

  • ExpectedException उदाहरण सार्वजनिक है ( संबंधित प्रश्न )
  • ExpectedException को @Before मेथड कहने पर त्वरित नहीं किया जाता है। यह पोस्ट स्पष्ट रूप से जुनीत के निष्पादन के आदेश की सभी जटिलताओं को स्पष्ट करती है।

ऐसा करें:

@Rule    
public ExpectedException expectedException;

@Before
public void setup()
{
    expectedException = ExpectedException.none();
}

अंत में, यह ब्लॉग पोस्ट स्पष्ट रूप से दिखाता है कि कैसे एक निश्चित अपवाद को फेंक दिया जाता है।


4

मैं लाइब्रेरी को फिर से शुरू करता हूं assertj-core जूनियर टेस्ट में अपवाद को संभालने के लिए को फिर से बनाया

जावा 8 में, इस तरह:

//given

//when
Throwable throwable = catchThrowable(() -> anyService.anyMethod(object));

//then
AnyException anyException = (AnyException) throwable;
assertThat(anyException.getMessage()).isEqualTo("........");
assertThat(exception.getCode()).isEqualTo(".......);

2

Java8 के साथ Junit4 समाधान इस फ़ंक्शन का उपयोग करने के लिए है:

public Throwable assertThrows(Class<? extends Throwable> expectedException, java.util.concurrent.Callable<?> funky) {
    try {
        funky.call();
    } catch (Throwable e) {
        if (expectedException.isInstance(e)) {
            return e;
        }
        throw new AssertionError(
                String.format("Expected [%s] to be thrown, but was [%s]", expectedException, e));
    }
    throw new AssertionError(
            String.format("Expected [%s] to be thrown, but nothing was thrown.", expectedException));
}

उपयोग तब है:

    assertThrows(ValidationException.class,
            () -> finalObject.checkSomething(null));

ध्यान दें कि finalलैम्ब्डा अभिव्यक्ति में एक ऑब्जेक्ट संदर्भ का उपयोग करने के लिए एकमात्र सीमा है । यह समाधान समाधान का उपयोग करके विधि स्तर पर thowable की अपेक्षा करने के लिए परीक्षण अभिक्रियाओं को जारी रखने की अनुमति देता है @Test(expected = IndexOutOfBoundsException.class)


1

उदाहरण के लिए, आप नीचे दिए गए कोड के टुकड़े के लिए जूनित लिखना चाहते हैं

public int divideByZeroDemo(int a,int b){

    return a/b;
}

public void exceptionWithMessage(String [] arr){

    throw new ArrayIndexOutOfBoundsException("Array is out of bound");
}

उपरोक्त कोड कुछ अज्ञात अपवाद के लिए परीक्षण करना है जो हो सकता है और नीचे एक कस्टम संदेश के साथ कुछ अपवाद को मुखर करना है।

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

private Demo demo;
@Before
public void setup(){

    demo=new Demo();
}
@Test(expected=ArithmeticException.class)
public void testIfItThrowsAnyException() {

    demo.divideByZeroDemo(5, 0);

}

@Test
public void testExceptionWithMessage(){


    exception.expectMessage("Array is out of bound");
    exception.expect(ArrayIndexOutOfBoundsException.class);
    demo.exceptionWithMessage(new String[]{"This","is","a","demo"});
}

1
    @Test(expectedException=IndexOutOfBoundsException.class) 
    public void  testFooThrowsIndexOutOfBoundsException() throws Exception {
         doThrow(IndexOutOfBoundsException.class).when(foo).doStuff();  
         try {
             foo.doStuff(); 
            } catch (IndexOutOfBoundsException e) {
                       assertEquals(IndexOutOfBoundsException .class, ex.getCause().getClass());
                      throw e;

               }

    }

यहाँ विधि को सही अपवाद के रूप में फेंकने की जाँच करने का एक और तरीका है या नहीं।


1

JUnit ढांचे में assertThrows()विधि है:

ArithmeticException exception = assertThrows(ArithmeticException.class, () ->
    calculator.divide(1, 0));
assertEquals("/ by zero", exception.getMessage());
  • JUnit 5 के लिए यह org.junit.jupiter.api.Assertionsकक्षा में है;
  • 4.13 जुइट के लिए यह org.junit.Assertकक्षा में है;
  • JUnit 4 के पुराने संस्करणों के लिए: बस org.junit.jupiter:junit-jupiter-apiअपनी परियोजना पर संदर्भ जोड़ें और आपको JUnit 5 से पूरी तरह से काम करने वाला संस्करण मिलेगा।

0

जावा 8 के साथ आप मापदंडों के रूप में अपवाद की जाँच करने और अपेक्षित कोड लेने के लिए एक विधि बना सकते हैं:

private void expectException(Runnable r, Class<?> clazz) { 
    try {
      r.run();
      fail("Expected: " + clazz.getSimpleName() + " but not thrown");
    } catch (Exception e) {
      if (!clazz.isInstance(e)) fail("Expected: " + clazz.getSimpleName() + " but " + e.getClass().getSimpleName() + " found", e);
    }
  }

और फिर अपने परीक्षण के अंदर:

expectException(() -> list.sublist(0, 2).get(2), IndexOutOfBoundsException.class);

लाभ:

  • किसी भी पुस्तकालय पर निर्भर नहीं
  • स्थानीयकृत जांच - अधिक सटीक और यदि आवश्यक हो तो एक परीक्षण के भीतर इस तरह के कई दावे करने की अनुमति देता है
  • प्रयोग करने में आसान
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.