2012-07-25 197 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); 
}