2017-01-22 39 views
0

我發現JUnit的文檔在下面的例子:JUnit和InterruptedException的

public static class HasGlobalLongTimeout { 

    @Rule 
    public Timeout globalTimeout= new Timeout(20); 

    @Test 
    public void run1() throws InterruptedException { 
     Thread.sleep(100); 
    } 

    @Test 
    public void infiniteLoop() { 
     while (true) {} 
    } 
} 

我明白,只要JUnit的嘗試中斷第一次測試,它會中斷線程在那裏上運行,它會拋出一個InterruptedException,導致測試結束。

但是第二個測試(infiniteLoop)呢?它不會拋出任何東西。超時後如何停止?

回答

1

超時規則在單獨的線程中運行每個測試,並等待超時。超時後,線程中斷。測試運動員將繼續進行下一個測試。它不會等待對中斷的任何響應,因此測試可以在後臺繼續運行。

infiniteLoop不會拋出任何InterruptedException但在運行任何剩餘測試時繼續運行。

所有測試完成後,運行測試的JVM通常會與其中的所有線程一起終止。要麼因爲線程被標記爲守護進程線程,要麼通過調用System.exit

見的源代碼:

+0

我從你的評論中瞭解到(在查看源代碼之後),junit會嘗試以超時方式加入該線程,並檢查它是否在超時後仍在運行。如果是,測試將失敗。即,即使測試在後臺運行,它在失敗的加入呼叫之後也會失敗。 – sapito

0

它應該在兩個測試中拋出,@Rule註釋將附加計時器給每個測試。如果測試運行超過20ms,則會觸發異常。所以在你的程序中,第二個測試也應該觸發InterruptedException。

+0

如果我們單獨進行第二項測試,該怎麼辦?即使有超時,它會永久運行嗎? – sapito

+0

不,它會拋出'InterrupedException',因爲它仍然有超時。註釋允許代碼將異常本地化到該測試,但在這種情況下,其他測試會拋出另一個異常。 –

+0

哪裏會拋出InterruptedException?這似乎讓我感到困惑:)看起來第二個測試不能拋出任何東西,它只是一個簡單的循環。 – sapito

0

我試過下面的代碼,它工作正常(即兩個測試因超時20ms而失敗)我正在使用Java 8和JUnit 4.12。

import java.util.concurrent.TimeUnit; 

import org.junit.Rule; 
import org.junit.Test; 
import org.junit.rules.Timeout; 

public class HasGlobalLongTimeout { 

    @Rule 
    public Timeout globalTimeout = new Timeout(20, TimeUnit.MILLISECONDS); 

    @Test 
    public void run1() throws InterruptedException { 
     Thread.sleep(100); 
    } 

    @Test 
    public void infiniteLoop() { 
     while (true) { 
     } 
    } 
} 

注意,我刪除了static修改類聲明(據我所知,這是不允許的類),我改變了Timeout聲明(即一個當前已過時)。