2015-02-07 96 views
4

比方說,你有這樣的單元測試方法有斷言而非異常時的最佳做法是什麼?

public Sprite spriteAt(int x, int y) 
{ 
    assert withinBorders(x, y) : "PRE: x and y should be inside the borders"; 

    return tileAt(x, y).topSprite(); 
} 

對戰

public Sprite spriteAt(int x, int y) 
{ 
    if (!withinBorders(x, y)) throw new InvalidArgumentException(); 

    return tileAt(x, y).topSprite(); 
} 

在底部的情況下,我通常有一個單元測試用例來檢查,如果有異常拋出的公共方法時無效值x和/或y如下給出:

@Test(expected = InvalidArgumentException.class) 
public void SpriteAt_InvalidX_ThrowsInvalidArgumentException() 
{ 
    sut.spriteAt(-100, 0); 
} 

這個測試用例是爲了確保在方法中實現參數驗證邏輯。

但是,對於頂部的斷言方法,我不知道我應該做什麼。斷言不是生產代碼,我認爲這意味着我不必測試斷言。另一方面,我認爲單元測試應該在方法中發生邏輯變化時通知開發人員失敗。如果我不寫一個測試用例來檢查是否有一個檢查無效參數的斷言(就像我如何處理異常方法一樣),那麼當意外刪除斷言行代碼時,我可能沒有意識到我犯了一個錯誤。

因此,我想要做的是檢查是否斷言是在地方,如果JUnit是運行啓用斷言,並沒有啓用斷言的時候沒有做任何事情。下面的代碼將包含僞代碼。

@Test 
public void SpriteAt_InvalidX_AssertionThrowsException() 
{ 
    if (assertion is enabled) 
    { 
     try 
     { 
      sut.spriteAt(-100, 0); 
      fail();  
     } 
     catch (AssertionFailureException e) 
     { 
     } 
    } 
} 

所以回到我的觀點。我想知道單元測試是否應該測試斷言。如果是這樣,我會朝着正確的方向前進嗎?如果不是的話,你如何防止在沒有單元測試的情況下意外刪除斷言代碼?

回答

2

有趣的問題。

在我看來,如果你想測試其中xy是不在範圍內明確應該比你扔IllegalArgumentException,而不是使用assert的情況。在另一方面,你有沒有方法評論認爲告訴的這種方法xy必須是一個範圍內的調用者。所以如果你從來電者的角度來看,你根本沒有權利斷言。 :-P

我會用assert檢查前置條件,我有沒有單元測試。但另一方面,你應該對這個例子進行單元測試。

在這一天結束時assert也拋出了RuntimeException,正如你所說的 - 只有在開發期間編譯器標誌是這樣。那麼爲什麼不簡單使用IllegalArgumentException這似乎完美的情況下。並且請給方法的調用者一個提示,在這種情況下,它會被拋出@throws評論。

我的結論:assert是完全沒有用處的,只要你有好的單元測試覆蓋率。它的僅適用於開發過程中的手動測試,以檢查不需要的前提條件或可以編寫明確的單元測試。

0

,如果你把它通過使用-ea java命令參數你隨時可以測試的assert功能。

assert拋出java.lang.AssertionError

單元測試應該測試的行爲,而不是實現。因此,如果在合同(JavaDoc)中未明確定義asert行爲,則不應該對其進行測試。

assert是相當無用的,幾乎從來沒有在真正的系統中使用。

+0

你能否解釋一下你的最後一句話?我也有說法是不是太重要了(除了單元測試)的感覺,但我還是大三。 – 2015-04-20 08:46:57

相關問題