考慮以下方法負面測試 - 我應該期待確切的例外嗎?
public void Foo(string str)
{
if (str == null)
throw new ArgumentNullException("str");
if (str.Length != 5)
throw new MyException();
}
假設我想爲它編寫像這樣一個負測試:
public void TestFoo()
{
try
{
Foo(null); //this could be an remote call (e.g. WCF)
Assert.Fail("Expected ArgumentNullException");
}
catch (ArgumentNullException) {} //should this be "Exception" instead?
try
{
Foo("four"); //this could be an remote call (e.g. WCF)
Assert.Fail("Expected MyException");
}
catch (MyException) {} //should this be "Exception" instead?
}
在我看來,那醒目如上一個特定的異常是一個實現細節,這可能使測試變得脆弱並且與實現(而不是接口)耦合。顯然MyException
可能會改變一天,但即使是ArgumentNullException
也可能被封裝在一些其他異常(例如未來的WCF行爲)中。通常,測試知道「四個」應該失敗,而這就是所關心的 - 失敗。
例外情況(沒有雙關語意)或許應該在異常被轉換成被傳遞給用戶的東西的情況下,如用戶友好的信息(例如,它被映射到用戶名已經採取UserNameTakenException
,嘗試不同的一個)。在這種情況下,您需要確保傳達正確的錯誤。即使這樣,它也有點問題,因爲它意味着每種可能的用戶錯誤都會有不同類型的異常,但這可能不會太糟糕(通常不會太多)。
我的思路是否有意義?我是否應該在不涉及面向用戶的異常的測試用例中捕獲通用的Exception
?
你不會在TestFoo中捕獲異常。您將該方法歸入預期的例外。 – phillip
您可能會因爲基於觀點而大吃一驚,但在我看來它非常有意義 - 在特定情況下拋出的異常是方法調用/ API的合同的一部分,因此應該通過測試來保護。 –
我想這取決於測試框架,雖然...如:Assert.Throws(()=> wmd.DoItNow()); –
phillip