qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請?jiān)L問 http://qaseven.github.io/

          Junit測試預(yù)期異常

            開發(fā)人員常常使用單元測試來驗(yàn)證的一段兒代碼的操作,很多時候單元測試可以檢查拋出預(yù)期異常( expected exceptions)的代碼。在Java語言中,JUnit是一套標(biāo)準(zhǔn)的單元測試方案,它提供了很多驗(yàn)證拋出的異常的機(jī)制。本文就探討一下他們的優(yōu)點(diǎn)。
            我們拿下面的代碼作為例子,寫一個測試,確保canVote() 方法返回true或者false, 同時你也能寫一個測試用來驗(yàn)證這個方法拋出的IllegalArgumentException異常。
            public class Student {
            public boolean canVote(int age) {
            if (i<=0) throw new IllegalArgumentException("age should be +ve");
            if (i<18) return false;
            else return true;
            }
            }
            (Guava類庫中提供了一個作參數(shù)檢查的工具類--Preconditions類,也許這種方法能夠更好的檢查這樣的參數(shù),不過這個例子也能夠檢查)。
            檢查拋出的異常有三種方式,它們各自都有優(yōu)缺點(diǎn):
            1.@Test(expected…)
            @Test注解有一個可選的參數(shù),"expected"允許你設(shè)置一個Throwable的子類。如果你想要驗(yàn)證上面的canVote()方法拋出預(yù)期的異常,我們可以這樣寫:
            @Test(expected = IllegalArgumentException.class)
            public void canVote_throws_IllegalArgumentException_for_zero_age() {
            Student student = new Student();
            student.canVote(0);
            }
            簡單明了,這個測試有一點(diǎn)誤差,因?yàn)楫惓诜椒ǖ哪硞€位置被拋出,但不一定在特定的某行。
            2.ExpectedException
            如果要使用JUnit框架中的ExpectedException類,需要聲明ExpectedException異常。
            @Rule
            public ExpectedException thrown= ExpectedException.none();
            然后你可以使用更加簡單的方式驗(yàn)證預(yù)期的異常。
            @Test
            public void canVote_throws_IllegalArgumentException_for_zero_age() {
            Student student = new Student();
            thrown.expect(NullPointerException.class);
            student.canVote(0);
            }
            或者可以設(shè)置預(yù)期異常的屬性信息。
            @Test
            public void canVote_throws_IllegalArgumentException_for_zero_age() {
            Student student = new Student();
            thrown.expect(IllegalArgumentException.class);
            thrown.expectMessage("age should be +ve");
            student.canVote(0);
            }
           除了可以設(shè)置異常的屬性信息之外,這種方法還有一個優(yōu)點(diǎn),它可以更加精確的找到異常拋出的位置。在上面的例子中,在構(gòu)造函數(shù)中拋出的未預(yù)期的(unexpected) IllegalArgumentException 異常將會引起測試失敗,我們希望它在canVote()方法中拋出。
            從另一個方面來說,如果不需要聲明就更好了
            @Rule
            public ExpectedException thrown= ExpectedException.none();
            它就像不需要的噪音一樣,如果這樣就很好了
            expect(RuntimeException.class)
            或者:
            expect(RuntimeException.class, “Expected exception message”)
            或者至少可以將異常和信息當(dāng)做參數(shù)傳進(jìn)去
            thrown.expect(IllegalArgumentException.class, “age should be +ve”);
            3.Try/catch with assert/fail
            在JUnit4之前的版本中,使用try/catch語句塊檢查異常
          @Test
          public void canVote_throws_IllegalArgumentException_for_zero_age() {
          Student student = new Student();
          try {
          student.canVote(0);
          } catch (IllegalArgumentException ex) {
          assertThat(ex.getMessage(), containsString("age should be +ve"));
          }
          fail("expected IllegalArgumentException for non +ve age");
          }
            盡管這種方式很老了,不過還是非常有效的。主要的缺點(diǎn)就是很容易忘記在catch語句塊之后需要寫fail()方法,如果預(yù)期異常沒有拋出就會導(dǎo)致信息的誤報(bào)。我曾經(jīng)就犯過這樣的錯誤。
            總之,這三種方法都可以測試預(yù)期拋出的異常,各有優(yōu)缺點(diǎn)。對于我個人而言,我會選擇第二種方法,因?yàn)樗梢苑浅>_、高效的測試異常信息。
          English »
           

          posted on 2014-10-08 09:12 順其自然EVO 閱讀(187) 評論(0)  編輯  收藏 所屬分類: 測試學(xué)習(xí)專欄

          <2014年10月>
          2829301234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 石嘴山市| 肇东市| 广河县| 永兴县| 伊川县| 临沭县| 涞源县| 民权县| 岚皋县| 桦甸市| 淮滨县| 凤冈县| 阿克苏市| 武平县| 克山县| 济南市| 巴中市| 玉树县| 阿合奇县| 射洪县| 治县。| 内乡县| 上虞市| 临江市| 中阳县| 二手房| 镇安县| 阿拉善右旗| 广丰县| 阳高县| 陆丰市| 赤峰市| 华安县| 古交市| 临沭县| 绩溪县| 肃北| 公主岭市| 抚宁县| 乐陵市| 临沭县|