2013-07-14 90 views
0

我是通過一個ScheduledExecutorService作爲合作者的單位TDDing。 這個單位有一個start方法,基本上啓動執行者的任務,我現在想寫驅動stop方法的測試,因爲我知道,由於沒有人會調用ScheduledExecutorService.shutdown線程將掛起(默認情況下不是守護進程線程)。如何編寫自未調用scheduledExecutorService.shutdown以來失敗的測試?

我想通過@Test(timeout = 5000L)做到這一點,並用實際的執行器服務構建單元(而不是確定性的),但是我面臨的問題是由於某種原因測試不能掛起。
我認爲,不確定,這與Intellij/Junit混合調用system.exit有關,並且會「殺死」我的jvm。

在我用main方法編寫的手冊「測試」中,我可以驗證在不調用shutdown方法的情況下系統確實停滯不前。

關於如何測試這個的任何想法?

感謝

更新
我已經把一個小的代碼示例這說明了這個問題:

public class SomethingTest { 
@Test(timeout = 5000L) 
public void shouldStopExecutorServiceWhenStopped2() throws InterruptedException { 
    ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); 
    Something cds = new Something(scheduler); 
    cds.start(); 
    Thread.sleep(2000); //this is to be pretty sure that the scheduling started since I'm not certain the thread will deterministically block otherwise 
} 

public static void main(String[] args) throws InterruptedException { 
    ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); 
    Something cds = new Something(scheduler); 
    cds.start(); 
    Thread.sleep(2000); //this is to be pretty sure that the scheduling started since I'm not certain the thread will deterministically block otherwise 
    cds.stop(); //comment this out to see that it hangs if shutdown isn't called 
} 
public static class Something { 
    private final ScheduledExecutorService scheduler; 

    public Something(ScheduledExecutorService scheduler) { 
     this.scheduler = scheduler; 
    } 

    public void start() { 
     scheduler.scheduleAtFixedRate(new Runnable() { 
      @Override 
      public void run() { 
       System.out.println("did something really important over time"); 
      } 
     }, 0, 5, TimeUnit.SECONDS); 
    } 

    public void stop() { 
     scheduler.shutdownNow(); 
    } 
} } 
+0

你爲什麼不嘲笑安排的執行器服務,並詢問模擬它是否被調用?我不確定我瞭解你的代碼的描述。爲什麼不自己編寫代碼,期望你期望它做什麼以及它做什麼呢? –

+1

@JBNizet我試圖遵循「只嘲弄你自己」的規則,所以我不想嘲笑執行者。我會在幾分鐘內發佈代碼的簡化版本。謝謝 – Ittai

+0

@JBNizet我已經添加了一個代碼示例。謝謝。 – Ittai

回答

1
從超時

除此之外,你應該有一個明確的規則,你將測試在你的情況。例如,讓測試運行一段時間(在你的情況下爲2秒),然後斷言它已經真正完成了它的工作,例如在你的調度器上對isTerminated()或isShutDown()進行了一些斷言。

但是,由於測試線程不會等待調度程序完成,因此您將運行測試的方式始終在5秒之前結束。

另一種選擇是把while循環這樣的(也可能是isShutDown()取決於你需要什麼):

while (!scheduler.isTerminated()) sleep(2000); 

這應該帶上你的測試,如果時間超過5秒失敗並且您將把您的測試線程等待,直到調度程序完成或調度程序的執行時間超過您設置的超時時間。

+0

謝謝b ut我寧願不公開執行者或它的方法,我不會僅僅用於測試 – Ittai

+0

嗯,這很好,但是你需要有一個你正在測試的規則。你製作一個新的TestRule的方法很好,但你不僅應該驗證守護進程線程,還應該能夠準確檢查你正在測試的線程,這樣你就不會搞亂其他的東西。 – Martin

+0

我想過,但我不知道這是真的,因爲在我的具體使用情況下,我試圖回答的需求是以「非卡住」系統結束,這意味着0個非守護線程 – Ittai

0

我想我要做的事(現在沒有時間了)是編寫一個與超時規則非常相似的JUnit TestRule,它檢查在完成之前是否有任何非守護線程正在運行。
本質上我想測試失敗,如果有任何非守護線程運行,因爲我想驗證系統將不會掛在此僞塊new unit();unit.start;unit.stop後,並且我知道如果沒有守護線程將不會掛起在一段時間後運行(輸入超時使測試確定並給予jvm選項以實際關閉該線程)。

相關問題