2013-05-28 34 views
2

我有一個多線程系統的功能測試。問題是系統使用System.exit,因此我的junit測試不會捕獲這些錯誤。所以我想我的測試失敗,如果某個地方System.exit被調用,即使在另一個線程。使System.exit在另一個線程的某處出現JUnit測試失敗

我以前Java: How to test methods that call System.exit()?,以防止對System.exit JVM停止,並拋出ExitException代替。我還用http://blog.cedarsoft.com/2011/12/junit-rule-fail-tests-on-exceptionsfailed-assertions-in-other-threads/來收集這些例外情況。 我希望我的測試在ExitException失敗後停止。但是這個異常只會停止當前線程。我試圖在拋出ExitException之前調用junitThread.interrupt(),但它僅適用於簡單測試。

我怎樣才能打破JUnit測試上,如果我不能修改線程創建代碼的任何線程拋出ExitException?

+0

也許這可以對你有所幫助:http://stackoverflow.com/questions/309396/java-how-to-test-methods-that-c​​all-system-exit –

回答

1

它爲什麼叫System.exit()?爲什麼它會在您的單元測試覆蓋的級別上調用System.exit()

如果你想測試退出碼,你的測試可以生成一個進程,並檢查按計劃它已經退出。如果你想測試其他功能,更好地構建你的應用程序,使得被測代碼不會有這樣惡劣的副作用。

雖然在一般,我想說的是具有獨立線程調用System.exit()是壞建築的重要指標。如果任何線程可以立即殺死整個應用程序而不會讓其他線程有機會清理,那麼很快就會遇到相當多的問題。

如果你的線程調用一些全球性停機處理程序(你可以在你的測試覆蓋),而不是System.exit()你不會有測試該功能的問題。

更新:當處理遺留代碼時,我的第一步是將System.exit()隔離到一個可以在測試中替換它的地方。例如。創建一個類是這樣的:

// "Singleton" with replaceable instance 
public class ShutdownHandler { 
    private static ShutdownHandler instance = new ShutdownHandler(); 

    public static ShutdownHandler getInstance() { 
     return instance; 
    } 

    public synchronized void shutdown() { 
     // default implementation 
     System.exit(); 
    } 

    public static void setInstance(ShutdownHandler newInstance) { 
     // (probably also check that this is only called in a test environment) 
     instance = newInstance; 
    } 
} 

然後用ShutdownHandler.getInstance().shutdown()替換所有System.exit()電話。這根本不會改變應用程序的功能。 但是現在你可以用一個實現替換你的測試中的ShutdownHandler實例,該實現設置了一些標誌+拋出異常而不是退出 - 然後你的測試可以檢查該標誌以確定應用是否退出。

我也可以推薦「有效合作與遺留代碼」,由羅伯特C.馬丁如何把一個老亂成什麼管理更多的想法。

+0

這段代碼是舊的,'System.exit ()'讓我感到驚訝。 – nickotinus