日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

谨慎使用JUnit的预期异常

發布時間:2023/12/3 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 谨慎使用JUnit的预期异常 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

有時,當我們收到對jOOQ或其他庫的拉取請求時,人們會將單元測試中的代碼更改為更“慣用的JUnit”。 特別是,這意味著他們傾向于更改此代碼(公認的不是那么漂亮的代碼):

@Test public void testValueOfIntInvalid() {try {ubyte((UByte.MIN_VALUE) - 1);fail();}catch (NumberFormatException e) {}try {ubyte((UByte.MAX_VALUE) + 1);fail();}catch (NumberFormatException e) {} }

…成為“更好”和“更清潔”的版本:

@Test(expected = NumberFormatException.class) public void testValueOfShortInvalidCase1() {ubyte((short) ((UByte.MIN_VALUE) - 1)); }@Test(expected = NumberFormatException.class) public void testValueOfShortInvalidCase2() {ubyte((short) ((UByte.MAX_VALUE) + 1)); }

我們獲得了什么?

沒有!

當然,我們已經必須使用@Test批注,因此我們不妨使用其expected的屬性對嗎? 我聲稱這是完全錯誤的。 有兩個原因。 當我說“兩個”時,我的意思是“四個”:

1.在代碼行數方面,我們并沒有真正獲得任何好處

比較語義上有趣的位:

// This: try {ubyte((UByte.MIN_VALUE) - 1);fail("Reason for failing"); } catch (NumberFormatException e) {}// Vs this: @Test(expected = NumberFormatException.class) public void reasonForFailing() {ubyte((short) ((UByte.MAX_VALUE) + 1)); }

給定或采用空格格式,基本語義信息量完全相同:

  • 該方法正在測試中的ubyte() 。 這不會改變
  • 我們要傳遞給失敗報告的消息(以字符串或方法名稱表示)
  • 異常類型和預期的事實
  • 因此,即使從樣式角度來看,這也不是真正有意義的更改。

    2.我們還是必須將其重構

    在注釋驅動的方法中,我所能做的就是測試異常類型 。 例如,在以后要添加更多測試的情況下,我無法對異常消息做出任何假設。 考慮一下:

    // This: try {ubyte((UByte.MIN_VALUE) - 1);fail("Reason for failing"); } catch (NumberFormatException e) {assertEquals("some message", e.getMessage());assertNull(e.getCause());... }

    3.單個方法調用不是單位

    單元測試稱為testValueOfIntInvalid() 。 因此, 通常在輸入無效的情況下,要測試的語義“單位”是UByte類型的valueOf()行為的語義“單位”。 不適用于單個值,例如UByte.MIN_VALUE - 1 。

    不應將其拆分為更小的單元,僅因為這是我們將@Test注釋塞入其功能范圍的唯一方法。

    TDD員工,請聽此。 我從不希望將我的API設計或我的邏輯塞進“落后”測試框架(沒有個人的,JUnit)所施加的一些怪異的限制中。 永不 ! “我的” API比“您的”測試重要100倍。 這包括我不想:

    • 公開一切
    • 使一切都沒有定論
    • 使一切都能注射
    • 使所有內容均為非靜態
    • 使用注釋。 我討厭注解。

    不。 你錯了。 Java已經不是一種太復雜的語言,但是讓我至少可以以我想要的任何方式使用它提供的一些功能。

    不要因為測試而在我的代碼上強加您的設計或語義上的毀損。

    好。 我反應過度了。 我總是在存在批注的情況下 。 因為…

    4.對于控制流結構而言,注釋始終是錯誤的選擇

    一次又一次,我為Java生態系統中的注釋濫用而感到驚訝。 注釋對三件事有好處:

  • 可處理的文檔(例如@Deprecated )
  • 方法,成員,類型等的自定義“修飾符”(例如@Override )
  • 面向方面的編程(例如@Transactional )
  • 并且要注意,@ @Transactional是使其成為主流的少數幾個真正有用的方面之一(日志掛鉤是另一個方面,或者,如果絕對必須的話,依賴注入)。 在大多數情況下,AOP是解決問題的利基技術,您通常在普通程序中不希望這樣做。

    用注解對控制流結構進行建模絕對不是一個好主意,更不用說測試行為了

    是。 Java已經采用了很長的(緩慢的)方法來包含更復雜的編程習慣用法。 但是,如果您對單元測試中偶爾的try { .. } catch { .. }語句的冗長性感到不滿,那么您可以找到解決方案。 是Java 8。

    如何使用Java 8更好地做

    JUnit lambda正在開發中: http : //junit.org/junit-lambda.html

    他們向新的Assertions類添加了新的功能API: https : //github.com/junit-team/junit-lambda/blob/master/junit5-api/src/main/java/org/junit/gen5/api /Assertions.java

    一切都基于Executable功能接口 :

    @FunctionalInterface public interface Executable {void execute() throws Exception; }

    該可執行文件現在可以用于實現斷言引發(或不引發)異常的代碼。 請參見Assertions的以下方法

    public static void assertThrows(Class<? extends Throwable> expected, Executable executable) {expectThrows(expected, executable); }public static <T extends Throwable> T expectThrows(Class<T> expectedType, Executable executable) {try {executable.execute();}catch (Throwable actualException) {if (expectedType.isInstance(actualException)) {return (T) actualException;}else {String message = Assertions.format(expectedType.getName(), actualException.getClass().getName(),"unexpected exception type thrown;");throw new AssertionFailedError(message, actualException);}}throw new AssertionFailedError(String.format("Expected %s to be thrown, but nothing was thrown.", expectedType.getName())); }

    而已! 現在,那些反對try { .. } catch { .. }塊的冗長的人可以重寫此代碼:

    try {ubyte((UByte.MIN_VALUE) - 1);fail("Reason for failing"); } catch (NumberFormatException e) {}

    …變成這樣:

    expectThrows(NumberFormatException.class, () -> ubyte((UByte.MIN_VALUE) - 1));

    如果我想對異常進行進一步檢查,可以這樣做:

    Exception e = expectThrows(NumberFormatException.class, () -> ubyte((UByte.MIN_VALUE) - 1)); assertEquals("abc", e.getMessage()); ...

    出色的工作,JUnit lambda團隊!

    函數式編程每次都會擊敗注釋

    注釋被濫用了很多邏輯 ,主要是在JavaEE和Spring環境中,它們都迫切希望將XML配置移回Java代碼。 這是錯誤的方法,這里提供的示例清楚地表明,與使用批注相比,幾乎總是有一種更好的方法可以使用面向對象或功能編程來顯式地寫出控制流邏輯。

    在@Test(expected = ...)的情況下,我得出結論:

    安息, expected

    (無論如何,它不再是JUnit 5 @Test批注的一部分)

    翻譯自: https://www.javacodegeeks.com/2016/01/use-junits-expected-exceptions-sparingly.html

    總結

    以上是生活随笔為你收集整理的谨慎使用JUnit的预期异常的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。