2010-08-18 19 views
1

如何確保在JUnit測試用例中,所有測試中的方法直接/間接產生的線程都是在那裏完成的,這樣我可以斷言最終結果?等待我在JUnit測試用例中測試的代碼產生的所有線程

@Test 
public void testMethod() { 
Result result=method();// may spawn multiple threads to set result.value 

Assert.assertTrue(result.getValue()==4); //should execute only after result.value is set to its final value. 
} 

回答

3

真正的問題是,你如何在你的非測試代碼中處理這種情況?當result.value將被設置時,method()的API向呼叫者保證什麼?

在編寫測試時牢記這一點 - 目的是聲明該類及其方法的行爲與他們的廣告一樣。有時候,確定廣告界面是什麼可能是挑戰的一半。

在這種情況下,我強烈建議您的Result對象的行爲類似於Future,因爲它的get()方法會阻塞,直到結果可用。 (或者,給它一個waitFor()方法或類似的)。

如果你的方法不提供任何具體保證或阻塞調用,所有你能真的做的測試是爲了繼續檢查每個X秒在一個循環中值,把一個@Timeout上測試確保該值設置在「合理」的時間。但這也是客戶所能做的,所以

  1. 這是一個非常有效的測試;
  2. 它強調接口不是非常適用於客戶端,修改它將是一個不錯的主意。
+0

+1您的解釋比我的方式更好:-) – 2010-08-18 15:22:19

1

我建議你調用方法()中多線程實例上的線程#加入,按照這種方式,所有的子線程都完成了。處理這種

0

一種方法需要兩個步驟:

  • 座主要測試線程在等待工作線程
  • 讓每個工作者線程信號中的主線程的工作完成後,疏導爲主當最後一名工人完成時進行線程。

理想情況下,如果所有工作人員都沒有在預期的時間範圍內完成,那麼您希望主線程超時並且測試失敗。這是非常簡單的使用ConcurrentUnit

public class MyTest extends ConcurrentTestCase { 
    @Test 
    public void test() throws Throwable { 
     int threads = 5; 
     for (int i = 0; i < threads; i++) { 
      new Thread(new Runnable() { 
       public void run() { 
        threadAssertEquals(1, 1); // Perform assertions as needed 
        resume(); 
       } 
      }).start(); 
     } 

     threadWait(1000, threads); // Wait for 5 resume calls 
    } 
}