JUnit终止子线程

当我测试创建子线程的方法的执行时,JUnit测试在子线程之前结束并杀死它。

我如何强制JUnit等待子线程完成其执行?

谢谢

在阅读了问题和一些评论之后,您需要的是一种用于unit testing异步操作的技术 。 doSomething()立即返回,但您希望测试代码等待其完成,然后进行一些validation。

问题是测试不知道调用产生的线程,所以显然它没有办法等待它们。 人们可以想到许多复杂的(也可能是有缺陷的)方法来解决这个问题,但在我看来,这里存在一个设计问题。 unit testing应该模拟某个API的客户端,它不应该假设任何有关实现的内容; 它应该只测试function,如API及其文档所反映的那样。 因此,我会避免尝试检测和跟踪异步调用创建的线程。 相反,如果需要,我会改进测试类的API。 异步调用所属的类应该提供一些检测终止的机制。 我可以想到3种方法,但可能还有更多:

1)允许注册一旦操作完成就收到通知的监听器

2)提供操作的同步版本。 该实现可以调用异步版本,然后阻塞直到完成。 如果类不应该暴露这样的方法,它的可见性可以减少到包保护,以便测试可以访问它。

3)在某些可见对象上使用wait-notify模式。

如果类没有提供这样的机制,那么它就不是真正可测试的,更糟糕​​的是,它可能也不是非常可重用的。

尝试在创建的线程上使用thread.join() 。 这将等待该线程死亡。

编辑:为避免这种情况,请尝试Thread.getThreadGroup().setDaemon(true); 在测试中,或者可能在setUp()方法中。 我没有测试过这个。

守护程序线程组在其最后一个线程停止或其最后一个线程组被销毁时会自动销毁。

我想知道JUnit是否在测试完成后立即调用System.exit()或其他东西。

@Eyal概述的基本技术是ConcurrentUnit的用途。 一般用法是:

  1. 产生一些线程
  2. 让主线程等待或睡眠
  3. 从工作线程中执行断言(通过ConcurrentUnit报告回主线程)
  4. 所有断言完成后,从其中一个工作线程恢复主线程

有关详细信息,请参阅ConcurrentUnit页面。

也许可以使用ExecutorService对线程进行分组,然后使用shutdown和awaitTermination方法?

条件是使用Runnable或Future,而不是Threads本身。

  while (s.isRunning()) { try { Thread.sleep(SLEEP_TIME); } catch (InterruptedException e) { e.printStackTrace(); } } 

您可以尝试阻止JUnit线程并让它等待您的线程完成。 需要Thread.sleep()以便您的线程不会占用CPU。 在这个例子中,s将是你需要有一个isRunning()方法的线程,这样你就可以检查线程是否仍然在每个SLEEP_TIME毫秒运行。 我知道这不是最好的解决方案,但是如果你只有2个线程并且你不希望JUnit杀死你的线程,这是有效的。 while循环导致此JUnit线程保持活动状态并等待您的其他线程完成。