2016-11-09 25 views
0

我正在嘗試爲一個名爲Student的類寫一些junit測試。基本上,每個學生都有一個studentNum,它被設置爲一個私有靜態int的迭代器。每次創建新學生時,studentNum都會增加。從junit測試類重置私有靜態int

我有一個函數的一些測試,從學生的數組列表中獲取studentNum爲1的學生。但是,每次我在新的測試中創建新的學生數組列表時,studentNum都會從之前測試的studentNum離開的位置開始。因此,第一次測試將使StudentNums從0到5的學生,第二次測試將使學生與6到11學生N.

我想知道是否有一種方法來重置我的測試中的私人靜態studentNum整數類,以便每次測試都可以從0開始。任何幫助將大大appreaciated。

+0

也許你想要在每次測試之前調用一個'@ Before'方法。 –

+0

你的代碼在哪裏? –

+0

只需在每種測試方法之前創建一個新的'Student'夾具。 – eckes

回答

2

每個學生有studentNum是一家民營靜態 INT

這種說法是沒有意義的。如果您的Student對象的每個實例都有自己的ID,那麼根據定義,id字段應該是而不是是靜態的。

+0

對不起,你是對的。實際上在Student類中有一個私有的靜態迭代器,studentNum在構造器中被設置。 – ThatOneGuy

0

看看@Before/@After註釋。像這樣註釋的方法在每個測試用例運行之前/之後被調用。您可以在那裏重置您的數據。

@Before 
public void setup(){ 

} 
3

事實上,你覺得這很難測試是一個警告標誌,你可能需要重新考慮你的設計。問問你自己:爲什麼Student類負責生成一個唯一的ID?

如果你將id生成邏輯(即使它像增加一個計數器一樣簡單)分成一個單獨的類,突然你可以在測試Student時嘲笑那個類,並讓它返回任何id你想在你的測試中。

+1

或者你只是在測試中用一個ID來實例化Student。 – chrylis

+1

@chrylis是的,如果需要,可以使用多種方法將id提供給學生對象。但重要的是單一職責原則:'Student'類不應該爲id的產生負責(或者保留實例的列表或類似的東西)。 – biziclop

-2

您可以使用Java的Reflection API將@Before@After(或兩者)重置爲您希望的任何值(例如0)的私有靜態字段。

這樣做將是這樣:

@Before 
public void setup() throws Exception { 
    Field studentNum = Student.class.getDeclaredField("studentNum"); 
    studentNum.setAccessible(true); //to overcome the visibility issue 
    studentNum.setInt(null, 0); //null since it's static 
} 
+2

儘管這種方法是可行的,但不應該使用它。訪問對象的私有成員(即使是測試)違反了OOP中最重要的原則:*信息隱藏*!另外:如果你開始測試實現細節(而不是ob行爲),如果你想重構你的代碼,你的測試會咬你。 –

+0

我同意你在測試中使用反射很可能是一種「代碼味道」。但是,您提出的建議是如何更好地構建代碼,以便保持良好的封裝和單一職責,使其在測試過程中可行,而OP則希望保持代碼原樣,但克服了可測試性問題,這是一個非常有效的場景,尤其是在舊/舊代碼的情況下,重構不是一個簡單的過程,並且很可能不值得(商業上的)。 – JChrist

+0

*「,而OP希望保持代碼原樣,但克服了可測試性問題」*何時是開始更好編碼的最佳時機?對我來說*現在*。爲OP提供反射解決方案使她能夠忍受破碎的編碼/測試風格。你*想要一個同事做OP的任務嗎? *我不! –

-1

試想一下什麼靜態decalration意味着... 對於真正的目的,應當持有學生獨特的數量studentNum不能是靜態的。使用靜態的所有Student對象都會有最新的StudentNum。

但是,如果這是一個要求(無法想象什麼...),只是爲了junit多個@Test方法(並且只有)R O M A N I A是正確的。這樣做:

@Before 
public void setUp() throws Exception { 
    Student.studentNum =0; 
} 

它會在執行每個@Test方法調用之前重置靜態studentNum。