2012-07-25 80 views
1

我想測試我的任務類,擴展javafx.concurrent.Task。我已經重寫了調用方法:啓動線程線程與任務類

public class myTask extends Task<Void> { 
    @Override 
    protected Void call() throws Exception { 
     while(!isCancelled()){ 
     doSth(); 
     } 
     return null; 
    } 
    } 

然後我想用一個JUnit測試來測試方法的調用:

public class MyTaskTest { 
    @Test 
    public void testCall() throws Exception { 
    MyTask task = new MyTask(); 
    Thread th = new Thread(task); 
    th.start(); 
    //.... further validation 
    } 
} 

但什麼都不做。在啓動的線程中沒有執行調用方法。有人可以解釋爲什麼是這樣嗎?

回答

1

JUnit測試不會等待您的任務線程完成所需的任務,並且只要JUnit線程完成就會終止。你可以看到的行爲用一個簡單的例子:

測試類:

public class Test1 implements Runnable { 
    @Override 
    public void run() { 
     System.out.println("I'm tired"); 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException ex) { 
     } 
     System.out.println("I'm done sleeping"); 
    } 

} 

測試類:

public class Test1Test { 
    @Test 
    public void testRun() { 
     Test1 task = new Test1(); 
     Thread th = new Thread(task); 
     th.start(); 
     boolean yourTestedStuff = true; 
     assertTrue(yourTestedStuff); 
    } 
} 

你會看到,當你運行測試,只打印「我m累了「,但不是」我完成了睡眠「(它可能甚至不打印」我很累「,這取決於線程交錯的方式)。

你可以做的是通過的CountDownLatch包裹你的任務在運行的某種形式與JUnit的線程同步的,例如,例如:

@Test 
public void testRun() throws InterruptedException { 
    final CountDownLatch latch = new CountDownLatch(1); 
    final Test1 task = new Test1(); 
    Runnable r = new Runnable() { //wrap your task in a runnable 

     @Override 
     public void run() { 
      task.run(); //the wrapper calls you task 
      latch.countDown(); //and lets the junit thread when it is done 
     } 
    }; 
    Thread th = new Thread(r); 
    th.start(); 
    assertTrue(latch.await(1000, TimeUnit.SECONDS)); //force junit to wait until you are done 
    boolean yourTestedStuff = true; 
    assertTrue(yourTestedStuff); 
}