আপনি কীভাবে দৃ do়তার সাথে বলতে পারেন যে ইউনাইট 4 পরীক্ষায় একটি নির্দিষ্ট ব্যতিক্রম ছোঁড়া হয়েছে?


1998

কিছু কোড একটি ব্যতিক্রম ছোঁড়ে তা পরীক্ষার জন্য আমি কীভাবে JUnit4 ব্যবহার করতে পারি?

যদিও আমি অবশ্যই এর মতো কিছু করতে পারি:

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

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

  assertTrue(thrown);
}

আমি স্মরণ করিয়ে দিচ্ছি যে এই ধরণের পরিস্থিতির জন্য একটি টিকা বা একটি Assert.xyz বা এমন কিছু যা ক্লুগি এবং JUnit এর আত্মার চেয়ে অনেক কম is


21
অন্য যে কোনও পদ্ধতির সাথে সমস্যা কিন্তু এটি হ'ল ব্যতিক্রম ছুঁড়ে ফেলার পরে তারা অবিচ্ছিন্নভাবে পরীক্ষাটি শেষ করে। আমি অন্যদিকে, org.mockito.Mockito.verifyব্যতিক্রম ছোঁড়ার আগে নির্দিষ্ট কিছু ঘটেছিল (যেমন কোনও লগার পরিষেবাটিকে সঠিক পরামিতি দিয়ে ডাকা হয়েছিল) তা নিশ্চিত করার জন্য আমি প্রায়শই বিভিন্ন পরামিতি সহ কল করতে চাই ।
জিরো ওয়ান

5
আপনি কীভাবে জুনিয়ট
জুন

6
@ জিরোওন - এর জন্য আমার দুটি আলাদা পরীক্ষা হবে - একটি ব্যতিক্রমের জন্য এবং একটিতে আপনার উপহাসের সাথে মিথস্ক্রিয়া যাচাই করতে।
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 না would কাজ org.junit.experimental.theories.Theories দ্বারা runned
Artem Oboturov

74
রায় ওশেরোভ আর্ট অফ ইউনিট টেস্টিংয়ে এই ধরণের ব্যতিক্রমী পরীক্ষাকে নিরুৎসাহিত করে , যেহেতু ব্যতিক্রমটি পরীক্ষার অভ্যন্তরেই নয় এবং কেবল পরীক্ষার অধীনে থাকা ইউনিটের ভিতরেই নয়।
কেভিন উইটটেক

21
আমি @ কিভিউ / রায় ওশেরভের সাথে একমত নই। আমার দৃষ্টিতে, পরীক্ষাগুলি আচরণের জন্য হওয়া উচিত, বাস্তবায়নের জন্য নয়। একটি নির্দিষ্ট পদ্ধতি কোনও ত্রুটি ফেলতে পারে তা পরীক্ষা করে আপনি সরাসরি পরীক্ষাগুলি প্রয়োগের সাথে বেঁধে রাখছেন। আমি যুক্তি দিয়ে বলব যে উপরে দেখানো পদ্ধতিতে টেস্টিং আরও মূল্যবান পরীক্ষা দেয়। আমি যে সাবধানতাটি যুক্ত করব তা হ'ল এই ক্ষেত্রে আমি একটি কাস্টম ব্যতিক্রমের জন্য পরীক্ষা করব, যাতে আমি জানতে পারি যে আমি সত্যিই চাই ব্যতিক্রমটি পাচ্ছি।
নিকবিডিয়ার

5
আমরাও। আমি ক্লাসের আচরণ পরীক্ষা করতে চাই। সবচেয়ে গুরুত্বপূর্ণ, আমি যদি এমন কিছু পুনরুদ্ধার করার চেষ্টা করি যা সেখানে নেই তবে আমি একটি ব্যতিক্রম পাই। তথ্য কাঠামোটি ArrayListযে সাড়া দেয় get()তা অপ্রাসঙ্গিক। আমি যদি ভবিষ্যতে কোনও আদিম অ্যারেতে যাওয়ার জন্য বেছে নিই, তবে আমাকে এই পরীক্ষার বাস্তবায়নটি পরিবর্তন করতে হবে। ডেটা কাঠামোটি গোপন করা উচিত, যাতে পরীক্ষাটি শ্রেণীর আচরণের উপর ফোকাস করতে পারে ।
নিকবিডিয়ার

1315

সম্পাদনা করুন: এখন যেহেতু JUnit 5 এবং JUnit 4.13 প্রকাশিত হয়েছে, সর্বোত্তম বিকল্পটি ব্যবহার করা হবে Assertions.assertThrows() (JUnit 5 এর জন্য) এবং Assert.assertThrows()(JUnit 4.13)। বিশদ জন্য আমার অন্যান্য উত্তর দেখুন ।

আপনি যদি 5 ইউনাইটে মাইগ্রেট না হয়ে থাকেন তবে আপনি ইউনাইট 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
@ স্কাফম্যান - যদি আমি এটি সঠিকভাবে বুঝতে পারি তবে মনে হচ্ছে ব্যতিক্রম। এক্সপেক্টটি কেবল একটি পরীক্ষার মধ্যে প্রয়োগ করা হচ্ছে, পুরো শ্রেণি নয়।
বাচার

5
আমরা যে ব্যতিক্রমটি ছুঁড়ে ফেলার আশা করি তা যদি একটি চেক করা ব্যতিক্রম হয় তবে আমরা কি থ্রো যুক্ত করতে পারি বা অন্যভাবে এই পরিস্থিতিটি পরীক্ষা করতে পারি?
মোহাম্মদ জাফর মাশহাদি

5
@ মার্টিনট্রামার কোনও কোডই foo.doStuff () এর পরে চালানো উচিত না যেহেতু ব্যতিক্রম নিক্ষেপ করা হয় এবং পদ্ধতিটি বেরিয়ে আসে। প্রত্যাশিত ব্যতিক্রমের পরে কোড থাকা (শেষ পর্যন্ত সংস্থানগুলি বন্ধ করার ব্যতীত) অসহনীয় কারণ যেহেতু ব্যতিক্রমটি ছুঁড়ে ফেলা হয় তা কখনই কার্যকর করা উচিত নয়।
জেসন থম্পসন

9
এটি সর্বোত্তম পন্থা। স্ক্যাফম্যানের সমাধানের তুলনায় এখানে দুটি সুবিধা রয়েছে। প্রথমত, ক্লাসটির ExpectedExceptionব্যতিক্রমগুলির বার্তাকে মেলাতে বা এমনকি ব্যতিক্রমের ক্লাসের উপর নির্ভর করে আপনার নিজের ম্যাচার লেখার উপায় রয়েছে। দ্বিতীয়ত, আপনি কোডটি যে রেখার ব্যতিক্রমটি ছুঁড়ে ফেলার আশা করছেন তার ঠিক আগেই আপনার প্রত্যাশা সেট করতে পারেন - যার অর্থ কোডের ভুল লাইন যদি ব্যতিক্রম ছুঁড়ে দেয় তবে আপনার পরীক্ষা ব্যর্থ হবে; যদিও স্কাফম্যানের সমাধান সহ এটি করার কোনও উপায় নেই।
দাউদ ইবনে কেরেম

5
@ এম জাফরম্যাশ যদি আপনি ছুঁড়ে ফেলতে চান এমন ব্যতিক্রমটি যদি পরীক্ষা করা হয়, তবে আপনি সেই ব্যতিক্রমটি পরীক্ষার পদ্ধতির থ্রো ক্লজের সাথে যুক্ত করতে পারেন। নির্দিষ্ট পরীক্ষার ক্ষেত্রে ব্যতিক্রমটি ট্রিগার না করা সত্ত্বেও আপনি কোনও পদ্ধতি পরীক্ষা করে যাচ্ছেন যা পরীক্ষা করা ব্যতিক্রম ছুঁড়ে দেওয়ার ঘোষণা দেওয়া হয় testing
নামশুব রাইটার

471

প্রত্যাশিত ব্যতিক্রম ব্যবহার করে সতর্ক থাকুন, কারণ এটি কেবলমাত্র দাবি করে যে পদ্ধতিটি সেই ব্যতিক্রমটিকে ছুঁড়ে দিয়েছে, পরীক্ষায় কোডের একটি নির্দিষ্ট লাইন নয় ।

আমি প্যারামিটারের বৈধতা যাচাই করার জন্য এটি ব্যবহার করার প্রবণতা রাখি কারণ এই জাতীয় পদ্ধতিগুলি সাধারণত খুব সহজ তবে আরও জটিল পরীক্ষাগুলি আরও ভালভাবে সরবরাহ করা যেতে পারে:

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

রায় প্রয়োগ করুন।


95
সম্ভবত আমি পুরানো স্কুল তবে আমি এখনও এটি পছন্দ করি। এটি আমাকেও ব্যতিক্রমটি নিজে যাচাই করার জন্য একটি জায়গা দেয়: কখনও কখনও আমার কাছে কিছু নির্দিষ্ট মানের জন্য ব্যতিক্রম হয়, বা আমি বার্তায় একটি নির্দিষ্ট মান সন্ধান করতে পারি (উদাহরণস্বরূপ "বার্তাটিতে" xyz "সন্ধান করা" অজানা কোড 'xyz' ")।
রডনি গিটজেল

3
আমি মনে করি নমশাব রাইটার এর পন্থা আপনাকে উভয় বিশ্বের সেরা দেয়।
এডি

4
এক্সপেক্টেড এক্সেপশন ব্যবহার করে আপনি এই ব্যতিক্রমের মতো পরীক্ষার জন্য পদ্ধতি অনুসারে এন ব্যাকশনেক্সটকে কল করতে পারেন ex এক্সপেক্ট (সূচিপত্র) ছাড়াই; foo.doStuff1 (); exception.expect (IndexOutOfBoundsException.class); foo.doStuff2 (); exception.expect (IndexOutOfBoundsException.class); foo.doStuff3 ();
ব্যবহারকারী 1154664

10
@ user1154664 আসলে, আপনি পারবেন না। এক্সপেক্টেড এক্সেপশন ব্যবহার করে আপনি কেবল এটি পরীক্ষা করতে পারেন যে একটি পদ্ধতি একটি ব্যতিক্রম ছুঁড়েছে, কারণ যখন সেই পদ্ধতিটি বলা হয়, তখন পরীক্ষাটি সঞ্চালন বন্ধ করে দেয় কারণ এটি প্রত্যাশিত ব্যতিক্রম ছুঁড়ে ফেলেছে!
নামশুব রাইটার

2
আপনার প্রথম বাক্যটি সত্য নয়। ব্যবহার করার সময় ExpectedException, সাধারণ কাজটি হ'ল আপনি যে রেখার ব্যতিক্রমটি ছুঁড়ে ফেলার আশা করছেন তার অবিলম্বে প্রত্যাশা সেট করা। এইভাবে, যদি কোনও পূর্ববর্তী লাইন ব্যতিক্রম ছুঁড়ে ফেলে, এটি নিয়মকে ট্রিগার করবে না এবং পরীক্ষাটি ব্যর্থ হবে।
দাউদ ইবনে কেরেম

212

পূর্বে উত্তর হিসাবে, JUnit- এ ব্যতিক্রমগুলি মোকাবেলার অনেকগুলি উপায় রয়েছে। তবে জাভা 8 এর সাথে আরও একটি রয়েছে: ল্যাম্বডা এক্সপ্রেশন ব্যবহার করে। লাম্বদা এক্সপ্রেশন দিয়ে আমরা এর মতো একটি সিনট্যাক্স অর্জন করতে পারি:

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

assertThrown একটি কার্যকরী ইন্টারফেস গ্রহণ করে, যার উদাহরণগুলি ল্যাম্বদা এক্সপ্রেশন, পদ্ধতি রেফারেন্স বা কনস্ট্রাক্টর রেফারেন্স সহ তৈরি করা যেতে পারে। assertTrrown যে ইন্টারফেসটি প্রত্যাশা করবে এবং একটি ব্যতিক্রম হ্যান্ডেল করতে প্রস্তুত হবে accepting

এটি তুলনামূলকভাবে সহজ তবে শক্তিশালী কৌশল।

এই কৌশলটি বর্ণনা করে এই ব্লগ পোস্টটি একবার দেখুন: http://blog.codeleak.pl/2014/07/ জুনিট-টেস্টিং- এক্সসেপশন-with-java-8-and-lambda-expressions.html

উত্স কোডটি এখানে পাওয়া যাবে: https://github.com/kolorobot/unit-testing-demo/tree/master/src/test/java/com/github/kolorobot/exception/java8

প্রকাশ: আমি ব্লগ এবং প্রকল্পের লেখক।


2
আমি এই সমাধানটি পছন্দ করি তবে আমি কি কোনও ম্যাভেন রেপো থেকে এটি ডাউনলোড করতে পারি?
সেলভিয়ান

মাভেন-এ উপলব্ধ এই ধারণার @ আর্ডাস্টারের একটি বাস্তবায়ন হ'ল স্টেফানবীরকনার.github.io/vallado
নামশুব রাইটার

6
@ ক্রিশ্চিয়ানোফোন্টস এই এপিআইয়ের একটি সহজ সংস্করণ জুনিয়ট 4.13 এর জন্য প্রস্তুত রয়েছে। Github.com/junit-team/junit/commit/…
নামশুব রাইটার

@ রাফলালবোরিয়েক প্রযুক্তিগতভাবে, new DummyService()::someMethodএটি একটি MethodHandleতবে ল্যাম্বডা অভিব্যক্তিগুলির সাথে এই পদ্ধতিটি সমানভাবে কাজ করে।
অ্যান্ডি

@NamshubWriter, মনে হয় যে junit 4.13 এর junit 5 পক্ষে পরিত্যক্ত হয়েছিল: stackoverflow.com/questions/156503/...
Vadzim

154

জুনেটে, ব্যতিক্রম পরীক্ষা করার জন্য চারটি উপায় রয়েছে।

junit5.x

  • জুনিট 5.x এর জন্য আপনি assertThrowsনিম্নলিখিত হিসাবে ব্যবহার করতে পারেন

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

junit4.x

  • জুনিট 4.x এর জন্য পরীক্ষার ঘোষণার ofচ্ছিক 'প্রত্যাশিত' বৈশিষ্ট্যটি ব্যবহার করুন

    @Test(expected = IndexOutOfBoundsException.class)
    public void testFooThrowsIndexOutOfBoundsException() {
        foo.doStuff();
    }
  • জুনিট 4.x এর জন্য, প্রত্যাশিত এক্সেক্সপশন নিয়মটি ব্যবহার করুন

    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 ম পছন্দ করা উচিত
    • যখন আপনি কেবল ব্যতিক্রমের ধরণের পরীক্ষা করতে চান তখন দ্বিতীয় উপায়টি ব্যবহৃত হয়
    • আপনি যখন পরীক্ষার ব্যতিক্রম বার্তাটি চান তখন প্রথম এবং শেষ দুটি ব্যবহার করা হয়
    • যদি আপনি জুনিট 3 ব্যবহার করেন তবে চতুর্থটি পছন্দ করা হয়
  • আরও তথ্যের জন্য, আপনি বিশদটির জন্য এই দস্তাবেজটি এবং জুনিট 5 ব্যবহারকারী গাইডটি পড়তে পারেন ।


6
আমার জন্য এটি সর্বোত্তম উত্তর, এটি সমস্ত উপায়ে খুব স্পষ্টভাবে কভার করেছে, ধন্যবাদ! ব্যক্তিগতভাবে আমি পঠনযোগ্যতার জন্য জুনিট 4 এর সাথে 3 য় বিকল্পটি ব্যবহার করা চালিয়ে যাচ্ছি, খালি ক্যাচ ব্লক এড়াতে আপনি থ্রোয়েবলও ধরতে পারেন এবং প্রকারের ই
নিকোলাস কর্নেটে

চেক করা ব্যতিক্রম প্রত্যাশা করা কি প্রত্যাশিত এক্সেক্সপশন ব্যবহার করা সম্ভব?
মিউসার

এটি সর্বোপরি শীর্ষ তিনটি উত্তরের সঞ্চার। আইএমও, এই উত্তরটি নতুন কিছু যুক্ত না করা থাকলেও পোস্ট করা উচিত ছিল না। খবরের জন্য কেবল উত্তর (একটি জনপ্রিয় প্রশ্ন)। খুব অকেজো।
পল সামসোথা

অবশ্যই, কারণ আপনি Trowableপদ্ধতি থেকে প্রাপ্ত যে কোনও ধরণের পাস করতে পারেন ExpectedException.expect। দয়া করে এটি স্বাক্ষর দেখুন । @miuser
ওয়ালশ

116

TL; ড

  • জেডিকে 8-পরবর্তী: ব্যতিক্রমী আচরণটি দৃsert় করতে AssertJ বা কাস্টম ল্যাম্বডাস ব্যবহার করুন।

  • প্রাক- JDK8: আমি পুরানো ভাল try- catchব্লক সুপারিশ করব । ( ব্লকের আগে একটি fail()দৃ add ়তা যুক্ত করতে ভুলবেন নাcatch )

জুনিট 4 বা JUnit 5 নির্বিশেষে।

দীর্ঘ গল্প

এটা নিজের লিখতে একটি সম্ভব এটি নিজে করবেন try - catchঅবরোধ করা বা JUnit সরঞ্জাম (ব্যবহার @Test(expected = ...)বা @Rule ExpectedExceptionJUnit নিয়ম বৈশিষ্ট্য)।

তবে এই উপায়গুলি এত মার্জিত নয় এবং অন্যান্য সরঞ্জামগুলির সাথে ভালভাবে পাঠযোগ্যতার সাথে মেশান না । তদুপরি, JUnit সরঞ্জামকরণের কিছু সমস্যা রয়েছে।

  1. দ্য try- catchব্লকটি আপনাকে পরীক্ষিত আচরণের চারপাশে ব্লকটি লিখতে হবে এবং ক্যাচ ব্লকে দৃser়তা লিখতে হবে, এটি সূক্ষ্ম হতে পারে তবে অনেকেই দেখতে পান যে এই স্টাইলটি পরীক্ষার পঠন প্রবাহকে বাধা দেয়। এছাড়াও, আপনাকে ব্লকের 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 ব্যবহারকারীদের খুব ভাল এই শৈলী জানি। কারও কারও পক্ষে এটি সুবিধাজনক হতে পারে তবে আপনি যদি আচরণের চালিত বিকাশ (বিডিডি) বা অ্যারেঞ্জ অ্যাক্ট অ্যা্যাসেট (এএএ) নীতিগুলি অনুসরণ করেন তবে ExpectedExceptionসেই লিখিত শৈলীতে এই বিধিটি উপযুক্ত নয়। @Testআপনি যে প্রত্যাশা রাখেন তার উপর নির্ভর করে এটি উপায় হিসাবে একই সমস্যা থেকে ভুগতে পারে As

    @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
    }

    এমনকি পরীক্ষার বিবৃতি দেওয়ার আগেও প্রত্যাশিত ব্যতিক্রম স্থানান্তরিত হয়, যদি পরীক্ষাগুলি বিডিডি বা এএএ অনুসরণ করে তবে এটি আপনার পড়া প্রবাহকে ভঙ্গ করে।

    এছাড়াও, এর লেখক JUnit এই মন্তব্য ইস্যু দেখুন ExpectedExceptionJUnit 4.13-beta-2 এমনকি এই প্রক্রিয়াটিকে হ্রাস করে:

    অনুরোধ টানুন # 1519 : প্রত্যাশিত প্রত্যাশাকে হ্রাস করুন

    পদ্ধতি Assert.assertThrows ব্যতিক্রমগুলি যাচাই করার জন্য একটি দুর্দান্ত উপায় সরবরাহ করে। তদ্ব্যতীত, টেস্টওয়্যাটচারের মতো অন্যান্য নিয়মের সাথে ব্যবহার করা হলে প্রত্যাশিত ধারণাটির ব্যবহার ত্রুটি-প্রবণ হয় কারণ ক্ষেত্রে নিয়মের ক্রম গুরুত্বপূর্ণ।

সুতরাং উপরের এই বিকল্পগুলির মধ্যে তাদের সমস্ত লোভনীয় সতর্কতা রয়েছে এবং কোডার ত্রুটিতে স্পষ্টভাবে প্রতিরোধী নয়।

  1. এই প্রকল্পটি তৈরি করার পরে আমি একটি প্রকল্প সচেতন হয়েছি যা প্রতিশ্রুতিবদ্ধ দেখাচ্ছে, এটি ধরা-ব্যতিক্রম catch

    প্রকল্পটির বিবরণ যেমনটি বলেছে, এটি কোনও কোডার ব্যতিক্রম ধরা কোডটির একটি সাবলীল রেখায় লিখতে দেয় এবং পরবর্তী দৃ as়তার জন্য এই ব্যতিক্রমটি সরবরাহ করে। এবং আপনি হ্যামক্রেস্ট বা অ্যাসেটজে-এর মতো যে কোনও আসক্তি পাঠাগার ব্যবহার করতে পারেন

    হোম পৃষ্ঠা থেকে নেওয়া একটি দ্রুত উদাহরণ:

    // 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 API ব্যবহার করবে (ব্যবহারের মতো assertThat(ex).hasNoCause()...)। এক পর্যায়ে প্রকল্পটি এসের্টজে-এর পূর্বপুরুষ ফেস্ট-অ্যাসেটের উপর নির্ভর করেসম্পাদনা: দেখে মনে হচ্ছে প্রকল্পটি একটি জাভা 8 লাম্বডাস সমর্থন তৈরি করছে।

    বর্তমানে, এই গ্রন্থাগারটিতে দুটি ত্রুটি রয়েছে:

    • এই লেখার সময়, এই লাইব্রেরিটি মকিতো 1.x এর উপর ভিত্তি করে বলা উচিত কারণ এটি দৃশ্যের পিছনে পরীক্ষিত বস্তুর একটি উপহাস তৈরি করে। মকিতো এখনও আপডেট না হওয়ায় এই পাঠাগারটি চূড়ান্ত শ্রেণি বা চূড়ান্ত পদ্ধতিতে কাজ করতে পারে না । এমনকি এটি বর্তমান সংস্করণে মকিতো 2-এর উপর ভিত্তি করে তৈরি করা হলেও, এটির জন্য একটি বিশ্বব্যাপী মক প্রস্তুতকারক ( inline-mock-maker) ঘোষণা করা দরকার যা আপনি যা চান তা নাও করতে পারে, কারণ এই মক মেকারের নিয়মিত মক প্রস্তুতকারকের বিভিন্ন ত্রুটি রয়েছে।

    • এটির জন্য আরও একটি পরীক্ষার নির্ভরতা প্রয়োজন।

    একবার লাইব্রেরি ল্যাম্বডাস সমর্থন করলে এই সমস্যাগুলি কার্যকর হবে না। তবে কার্যকারিতা AssertJ সরঞ্জামসেট দ্বারা নকল করা হবে।

    আপনি যদি ক্যাচ-ব্যতিক্রম সরঞ্জামটি ব্যবহার করতে না চান তবে সমস্ত বিবেচনায় রেখে, আমি কমপক্ষে জেডিকে 7 পর্যন্ত try- catchব্লকের পুরানো ভাল উপায়ের পরামর্শ দেব। এবং জেডিকে 8 ব্যবহারকারীর জন্য আপনি অ্যাসেটজে ব্যবহার করতে পছন্দ করতে পারেন কারণ এটি অফারগুলি কেবল ব্যাতিক্রমকে দৃ .় করার চেয়ে বেশি।

  2. জেডিকে 8 এর সাথে, ল্যাম্বডাস পরীক্ষার দৃশ্যে প্রবেশ করে এবং তারা ব্যতিক্রমী আচরণটি দৃsert় করার একটি আকর্ষণীয় উপায় হিসাবে প্রমাণিত হয়েছে। ব্যতিক্রমী আচরণ দাবী করার জন্য একটি দুর্দান্ত সাবলীল এপিআই সরবরাহ করতে AssertJ আপডেট করা হয়েছে।

    এবং 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. জুনেট 5-এর একটি সম্পূর্ণ-সম্পূর্ণ পুনর্লিখনের সাথে, দাবিগুলি কিছুটা উন্নত করা হয়েছে , সঠিকভাবে ব্যতিক্রম প্রমাণ করার জন্য তারা বক্সের বাইরে উপায় হিসাবে আকর্ষণীয় প্রমাণ করতে পারে। তবে সত্যিই দৃ the়তা এপিআইটি এখনও কিছুটা দরিদ্র, এর বাইরে কিছুই নেই 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 এর ব্যবহারের সহজলভ্যতা, আবিষ্কারযোগ্য এপিআই, উন্নয়নের দ্রুত গতি এবং ডি-ফ্যাক্টো পরীক্ষার নির্ভরতা হিসাবে পরীক্ষার কাঠামো নির্বিশেষে জেডি কে 8 এর সাথে সেরা সমাধান (জুনিট বা না), পূর্ববর্তী জেডিকে পরিবর্তে নির্ভর করা উচিত try-catch এমনকি যদি তারা মনে করে তবে ব্লকগুলি।

এই উত্তরটি অন্য প্রশ্ন থেকে অনুলিপি করা হয়েছে যা একই দৃশ্যমানতা নয়, আমি একই লেখক।


1
অরগা.জুনিট.জুপিটার যুক্ত করা: জুনিট-বৃহস্পতি-ইঞ্জিন: 5.0.0-আরসি 2 নির্ভরতা (ইতিমধ্যে বিদ্যমান জুনিট ছাড়াও: জুনিট: 4.12) অ্যাসেটটি ব্যবহার করতে সক্ষম হবেন সম্ভবত পছন্দসই সমাধান নয়, তবে কোনও কারণ হয়নি আমার জন্য সমস্যা।
anre

আমি প্রত্যাশিত এক্সেসপশন নিয়মটি ব্যবহার করার এক অনুরাগী কিন্তু এটি সর্বদা আমাকে বিরক্ত করে যে এটি এএএর সাথে ভেঙে যায়। সমস্ত ভিন্ন পদ্ধতির বর্ণনা দেওয়ার জন্য আপনি একটি দুর্দান্ত নিবন্ধ লিখেছেন এবং আপনি অবশ্যই আমাকে AssertJ :-) চেষ্টা করতে উত্সাহিত করেছেন ধন্যবাদ!
পিম হাজেব্রুক

পিমহাজেব্রোক ধন্যবাদ AssertJ API যথেষ্ট সমৃদ্ধ। আমার মতে আরও ভাল যে JUnit বক্সের বাইরে প্রস্তাব দেয়।
ব্রাইস

64

এখন যেহেতু JUnit 5 এবং JUnit 4.13 প্রকাশিত হয়েছে, সর্বোত্তম বিকল্পটি ব্যবহার করা হবে Assertions.assertThrows() (JUnit 5 এর জন্য) এবং Assert.assertThrows()(JUnit 4.13)। জুনিট 5 ব্যবহারকারী গাইড দেখুন See

এখানে একটি উদাহরণ রয়েছে যা যাচাই করে যে একটি ব্যতিক্রম নিক্ষেপ করা হয় এবং এটি ব্যতিক্রম বার্তায় দৃ make়তার জন্য সত্য ব্যবহার করে:

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. ল্যাম্বডায় কোডটি যদি ব্যতিক্রম না ফেলে এবং একটি স্ট্যাকট্রেস যদি আলাদা ব্যতিক্রম ছুঁড়ে দেয় তবে আপনি একটি দরকারী ব্যতিক্রম বার্তা পাবেন get
  3. সংক্ষিপ্ত
  4. আপনার পরীক্ষাগুলিকে অ্যারেঞ্জ-অ্যাক্ট-এসার্ট অনুসরণ করতে অনুমতি দেয়
  5. আপনি কোন কোডটি ব্যতিক্রমটি ছুঁড়ে ফেলার আশা করছেন তা আপনি অবশ্যই সূচিত করতে পারেন can
  6. আপনার মধ্যে প্রত্যাশিত ব্যতিক্রম তালিকাভুক্ত করার দরকার নেই throws দফা
  7. ধরা পড়া ব্যতিক্রম সম্পর্কে দৃser়তা জানাতে আপনি নিজের পছন্দের দৃ as়তার কাঠামোটি ব্যবহার করতে পারেন

একই জাতীয় পদ্ধতিতে org.junit Assertইউনাইট 4.13 এ যুক্ত করা হবে ।


এই পদ্ধতিটি পরিষ্কার, তবে আমি দেখতে পাচ্ছি না এটি কীভাবে আমাদের পরীক্ষাকে "অ্যারেঞ্জ-অ্যাক্ট-অ্যাসেট" অনুসরণ করতে দেয়, যেহেতু আমাদের "আইন" অংশটি একটি "অ্যাসিটারথ্রো" তে আবৃত করতে হয়, যা একটি দাবী।
ক্লকওয়ার্ক

@ ক্লকওয়ার্ক ল্যাম্বদা হ'ল "আইন"। অ্যারেঞ্জ-অ্যাক্ট-এ্যাসেটের লক্ষ্য কোডটি পরিষ্কার এবং সহজ করা (এবং তাই বোঝা ও বজায় রাখা সহজ)। যেমনটি আপনি বলেছেন, এই পদ্ধতিটি পরিষ্কার।
নামশুব রাইটার

আমি এখনও আশা করছিলাম যে পরীক্ষার শেষে আমি থ্রো এবং ব্যতিক্রমটি দৃ as় করতে পারব যদিও "দৃ as়" অংশে। এই পদ্ধতির ক্ষেত্রে আপনাকে প্রথমে এটি ধরার জন্য প্রথমে দৃsert়তার সাথে কাজটি মোড়ানো দরকার।
ক্লকওয়ার্ক

প্রতিবেদনের জন্য প্রতিটি পরীক্ষায় আরও কোডের প্রয়োজন হবে। এটি আরও কোড এবং ত্রুটি-প্রবণ হবে।
নামশুব রাইটার

42

এটি সম্পর্কে কীভাবে: খুব সাধারণ ব্যতিক্রমটি ধরুন, নিশ্চিত করুন এটি এটিকে ক্যাচ ব্লক থেকে আউট করে তোলে, তারপরে জোর দিয়ে নিন যে ব্যতিক্রমটির শ্রেণিটি আপনি যা প্রত্যাশা করছেন তা। এই দাবিটি ব্যর্থ হবে যদি ক) ব্যতিক্রমটি ভুল ধরণের হয় (যেমন, পরিবর্তে যদি আপনি নাল পয়েন্টার পেয়ে থাকেন) এবং খ) ব্যতিক্রমটি কখনও নিক্ষেপ করা হয়নি।

public void testFooThrowsIndexOutOfBoundsException() {
  Throwable e = null;

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

  assertTrue(e instanceof IndexOutOfBoundsException);
}

3
এছাড়াও, আপনি পরীক্ষা দেখতে পাবেন না যে দিনটি যখন পরীক্ষায় ব্যর্থ হয় তখন পরীক্ষার ফলাফলগুলিতে কী ধরণের ব্যতিক্রম হয় ex
jontejj

আপনি কীভাবে শেষে দৃsert়ভাবে বলছেন তা পরিবর্তন করে এটি কিছুটা উন্নত হতে পারে। assertEquals(ExpectedException.class, e.getClass())যখন পরীক্ষা ব্যর্থ হয় তখন আপনাকে প্রত্যাশিত এবং আসল মানগুলি দেখায়।
সাইফার


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)পরীক্ষার মধ্যে প্রত্যাশিত রেখার গ্যারান্টি দেয় বলে এটি আরও ভাল the

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

মাভেন / গ্রেডল নির্দেশাবলী এখানে।


অত্যন্ত সংক্ষিপ্ত উপায়ে এবং কেউ এটির প্রশংসা করেন না, আশ্চর্যজনক .. আমার কেবলমাত্র assertJ লাইব্রেরিতে একটি সমস্যা আছে, জুনেটের সাথে নাম অনুসারে দ্বন্দ্বগুলি দ্বন্দ্ব রয়েছে। অ্যাসেটজে থ্রোবি সম্পর্কে আরও জানুন: ইউনিত: জাভা 8 এবং আসরেটজে 3.0.0 এর সাথে টেস্টিং ব্যতিক্রমগুলি le Codeleak.pl
ycomp

@comp ভাল এটি একটি খুব পুরানো প্রশ্নের নতুন উত্তর, সুতরাং স্কোর পার্থক্য প্রতারণামূলক।
ওয়েস্টন

কেউ সম্ভবত জাভা 8 এবং অ্যাসেটজে ব্যবহার করতে পারেন তবে এটিই সেরা সমাধান!
পিয়েরে হেনরি

@ আইকম্প আমি সন্দেহ করি যে এই নামটির দ্বন্দ্ব ডিজাইনের দ্বারা হতে পারে: অ্যাসেটজে লাইব্রেরি আপনাকে দৃU়ভাবে উত্সাহ দেয় যে আপনি কখনই assertThatইউএনইটি, সর্বদা অ্যাসেটজে ব্যবহার করবেন না । এছাড়াও JUnit পদ্ধতিটি কেবল একটি "নিয়মিত" টাইপ দেয়, যেখানে AssertJ পদ্ধতি একটি AbstractAssertসাবক্লাস প্রদান করে ... উপরের মতো পদ্ধতিগুলির স্ট্রিংকে অনুমতি দেয় (বা এর জন্য প্রযুক্তিগত শর্তগুলি যাই হোক না কেন ...)।
মাইকে রডেন্ট

@ ওয়েস্টন আসলে আমি আপনার কৌশলটি সবেমাত্র এএসেটজে ২.০.০ এ ব্যবহার করেছি। আপগ্রেড না করার জন্য কোনও অজুহাত, সন্দেহ নেই, তবে যদিও আপনি এটি জানতে পছন্দ করতে পারেন।
মাইকে রডেন্ট

33

একই সমস্যা সমাধানের জন্য আমি একটি ছোট প্রকল্প স্থাপন করেছি: http://code.google.com/p/catch-exception/

এই ছোট সহায়ক ব্যবহার করে আপনি লিখতে হবে

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

এটি JUnit 4.7 এর প্রত্যাশিত এক্সেসপশন নিয়মের তুলনায় কম ভার্বোজ। স্কাফম্যান দ্বারা প্রদত্ত সমাধানের তুলনায় আপনি কোন রেখার কোডটি ব্যতিক্রমটি আশা করবেন তা নির্দিষ্ট করতে পারেন। আশা করি এটা কাজে লাগবে.


আমি এটির মতো কিছু করার বিষয়েও ভেবেছিলাম, তবে শেষ পর্যন্ত আবিষ্কার করেছি যে প্রত্যাশিত ধারণাটির আসল শক্তিটি কেবলমাত্র আপনি প্রত্যাশিত ব্যতিক্রম নির্দিষ্ট করতে পারবেন না, তবে আপনি ব্যতিক্রমের নির্দিষ্ট বৈশিষ্ট্য যেমন প্রত্যাশিত কারণ বা প্রত্যাশিত বার্তাও নির্দিষ্ট করতে পারেন।
জেসন থম্পসন

আমার ধারণা হ'ল এই দ্রবণে কিছুটা অসুবিধাগুলিও রয়েছে? উদাহরণস্বরূপ, যদি 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 ব্যবহার করে আসল উত্তর।

পরীক্ষার বিভিন্ন উপায় রয়েছে যে একটি ব্যতিক্রম নিক্ষেপ করা হয়। আমি আমার পোস্টে নীচের বিকল্পগুলি নিয়েও আলোচনা করেছি কীভাবে জুনিয়নের সাথে দুর্দান্ত ইউনিট পরীক্ষা লিখতে হয়

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 উইকিতে ব্যতিক্রম টেস্টিং সম্পর্কে আরও পড়তে পারেন এবং খারাপ rorobot - ব্যতিক্রম প্রত্যাশা JUnit বিধি


22

আপনি এটি করতে পারেন:

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

12
JUnit টেস্টে, আপনার পরীক্ষাগুলি এমন পরিবেশে চালিত হয় যেখানে দৃser়তা সক্ষম করা Assert.fail()না হয় assertকেবল সে ক্ষেত্রে এটি ব্যবহার করা ভাল better
নামশুব রাইটার

14

আইএমএইচও, 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 আরো infos http://junit.org/junit5/docs/current/user-guide/#writing-tests-assertions


expectThrows()একটি অংশ টেস্টএনজি, কোনও জুনিত নয়
লু 55

13

জুনিত 4-এর সর্বাধিক নমনীয় এবং মার্জিত উত্তরটি আমি মাইকিয়ং ব্লগে পেয়েছি । এটিতে টীকাটি 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-tom প্রযুক্তিগতভাবে এটি দুটি পৃথক পদক্ষেপ, তারা কেবল এই ক্রমে নয়। ; পি
ট্রেজকাজ

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

আমার ক্ষেত্রে আমি সর্বদা ডিবি থেকে রানটাইমএক্সসেপশন পাই তবে বার্তাগুলি পৃথক হয়। এবং ব্যতিক্রম যথাক্রমে পরিচালনা করা প্রয়োজন। এখানে আমি এটি পরীক্ষা করেছি:

@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

পদ্ধতিটির পরে আমরা দৃ exception় ব্যর্থতাটি ব্যবহার করতে পারি যা অবশ্যই একটি ব্যতিক্রম প্রত্যাবর্তন করতে পারে:

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স্ট্যাক ট্রেসটি গ্রাস করবে যদি অন্য কিছু ব্যতিক্রম ছুঁড়ে দেওয়া হয়, দরকারী তথ্য হারাতে পারে
নমশাবউইথর

5

নমশব রাইটার যা বলেছে তা যোগ করার সাথে সাথে তা নিশ্চিত করুন:

  • প্রত্যাশিত এক্সেপশন উদাহরণটি সর্বজনীন ( সম্পর্কিত প্রশ্ন )
  • প্রত্যাশিত অনুগ্রহটি @ পূর্ব পদ্ধতিটি বলে তাত্ক্ষণিকভাবে তৈরি হয় না । এই পোস্টটি JUnit এর মৃত্যুদন্ড কার্যকর করার আদেশের সমস্ত জটিলতা পরিষ্কারভাবে ব্যাখ্যা করেছে

এটি করবেন না :

@Rule    
public ExpectedException expectedException;

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

শেষ অবধি, এই ব্লগ পোস্টটি স্পষ্টভাবে তুলে ধরেছে যে কীভাবে একটি নির্দিষ্ট ব্যতিক্রম ছুঁড়ে দেওয়া আছে sert


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

জাভা 8 সহ জুনিট 4 সমাধানটি এই ফাংশনটি ব্যবহার করতে হবে:

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ল্যাম্বডা এক্সপ্রেশনটিতে অবজেক্টের রেফারেন্সটি ব্যবহার করা একমাত্র সীমাবদ্ধতা । এই সমাধানটি সমাধানের সাহায্যে পদ্ধতি স্তরে থোবাবলের প্রত্যাশার পরিবর্তে পরীক্ষার দাবিগুলি চালিয়ে যাওয়ার অনুমতি দেয় @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());
  • জুনিয়ট 5 এর জন্য এটি org.junit.jupiter.api.Assertionsক্লাসে রয়েছে;
  • JUnit 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);

উপকারিতা:

  • কোন লাইব্রেরি উপর নির্ভর না
  • স্থানীয়ীকৃত চেক - আরও সুনির্দিষ্ট এবং যদি প্রয়োজন হয় তবে এক পরীক্ষার মধ্যে এই জাতীয় একাধিক সংস্থান থাকতে পারে
  • ব্যবহার করা সহজ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.