2011-10-11 94 views
0

我正在處理的情況是,根據聲明的順序,我的測試通過或失敗。這當然指向不正確的隔離測試。但我很難理解如何去尋找問題。 事情是我的junit測試派生自一個屬於在junit上構建的測試框架並具有一些依賴注入容器的類。容器被基類設置重置爲每個測試,所以至少在容器中沒有延遲的對象,因爲容器本身是新的。所以我傾向於以下場景。如何解決間歇性junit測試失敗問題?

  1. test1間接導致某些classA將classA.somestaticMember設置爲xyz值。測試obj不直接維護對classA的任何引用 - 但是當test1結束時,classA仍然由vm通過值xyz加載。
  2. test2訪問classA並跳到某個具有xyz值的靜態成員上。

問題是a)我不知道這是否確實如此 - 我該如何去尋找?我似乎無法找到代碼中的靜態變量的引用... b)有沒有辦法告訴junit轉儲所有已加載的類並重新執行每個測試方法?

+1

如果您的測試依賴於執行順序而失敗,那麼它們並不是真正的單元測試。那,或者你沒有利用夾具。 – cHao

回答

1

你可以聲明的方法與@Before,像

@Before public void init() 
{ 
    // set up stuff 
} 

和JUnit將在每次測試之前運行它。你可以用它來建立一個「夾具」(一組已知的新對象,數據等,你的測試可以獨立工作)。

還有一個@After,你可以使用進行任何清理,每次測試後。您通常不需要這樣做,因爲Java將清理您使用的任何對象,但它可能對於將外部對象(您不創建和控制的對象)恢復到已知狀態很有用。 (注意,如果你爲了做測試而依賴外部對象,那麼你所擁有的不再是單元測試,你不能真正說出失敗是由於你的代碼或外部對象,這是單元測試的目的之一)。

+0

我同意 - 它不是「單元」測試。自從我使用完整的外部對象以來,它更多地是功能/集成測試。不過,我對這件事沒有多少發言權。只有HAVING測試是一個巨大的改進,而不是沒有。我正在使用junit 3.8和setup和teardown方法,但對於外部對象,我該如何重新初始化? – treefrog

+0

@treefrog:取決於你的DI框架和/或你的對象。您需要能夠用已知的新物體替換物體,或者在必要時手動「重置」現有物體。例如,如果您的外部對象是數據庫,請刪除所有舊數據,然後插入足夠的數據以進行所有測試。或者對於文件,刪除文件或放回或用已知版本替換它。對於網絡的東西,關閉連接並重新啓動它。重點是,*撤消任何副作用*您的測試可能導致 - 每個測試的環境應該完全相同。 – cHao

+0

是的,我明白這是我需要做的 - 我正在尋找方法來完成 - junit提供了一種方法來指定一個單獨的類加載器來加載測試嗎?或者可能是我需要遍歷所有由類加載器加載的類並通過反射進行清理 - 我想不出任何其他方式 – treefrog