@Test
public void myTest() {
CountDownLatch countDownLatch = new CountDownLatch(1);
new Thread(new Runnable() {
@Override
public void run() {
//write your logic here
countDownLatch.countDown();
}
}).start();
//wait until the child thread completed.
countDownLatch.await();
}
5条答案
按热度按时间cyej8jka1#
在阅读了问题和一些注解之后,似乎您需要的是一种对异步操作进行单元测试的技术。doSomething()立即返回,但是您希望测试代码等待其完成,然后进行一些验证。
问题是测试并不知道调用所产生的线程,所以显然它没有办法等待它们。人们可以想到许多复杂的(可能有缺陷的)方法来解决这个问题,但在我看来这里有一个设计问题。单元测试应该模拟某个API的客户端,它不应该假设任何关于实现的事情;它应该只测试功能,正如API和它的文档所反映的那样。因此,我将避免试图检测和跟踪由异步调用创建的线程。相反,如果需要的话,我将改进被测试类的API。异步调用所属的类应该提供一些检测终止的机制。我可以想到3种方法,但可能还有更多:
1.允许注册在操作完成后收到通知的监听程序
1.提供作业的同步版本。实作可以呼叫异步版本,然后封锁直到完成为止。如果类别不应该公开这样的方法,则可以将其可视性降低为封装保护,以便测试可以存取它。
1.在某个可见对象上使用wait-notify模式。
如果类没有提供这样的机制,那么它就不是真正可测试的,更糟糕的是,它可能也不是很可重用。
7rtdyuoh2#
尝试在创建的线程上使用thread.join()。这将等待该线程终止。
编辑:为了避免这种情况,在测试中尝试
Thread.getThreadGroup().setDaemon(true);
,或者在setUp()
方法中尝试。当守护程序线程组的最后一个线程停止或最后一个线程组被销毁时,守护程序线程组将自动销毁。
但是,我想知道JUnit是否会在测试完成后立即调用
System.exit()
或其他函数。5f0d552i3#
也许用一个ExecutorService对线程进行分组,然后使用shutdown和waitTermination方法?
条件是使用Runnable或Future,而不是线程本身。
e5nszbig4#
您可以尝试阻塞JUnit线程,让它等待您的线程完成。需要
Thread.sleep()
,这样您的线程就不会占用CPU。在这个例子中,s将是您的线程,您需要有一个isRunning()
方法,这样您就可以每隔SLEEP_TIME
毫秒检查一次线程是否仍在运行。我知道这不是'这是最好的解决方案,但是如果你只有2个线程,并且你不想让JUnit杀死你的线程,这是可行的。while循环使这个JUnit线程保持活动状态,等待另一个线程完成。svgewumm5#
在java中,尝试使用CountDownLatch使主线程等待,直到子线程完成。