如何使用 junit 测试阻塞方法

How can I test a blocking method using junit

我有一个 class 有一个阻塞的方法,我想验证它是否阻塞。方法如下图

 public static void main(String[] args) {

    // the main routine is only here so I can also run the app from the command line
    applicationLauncherInstance.initialize();

    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            if (null != application) {
                applicationLauncherInstance.terminate();
            }
        }
    });

    try {
        _latch.await();
    } catch (InterruptedException e) {
        log.warn(" main : ", e);
    }
    System.exit(0);
}

如何为这种方法编写单元测试。我还没开始就卡住了。

public class ApplicationLauncherTest extends TestCase {


    public void testMain() throws Exception {
        ApplicationLauncher launcher = new ApplicationLauncher();
    }
}

感谢 Kulu,我找到了解决方案。

public void testMain() throws Exception {
    Thread mainRunner = new Thread(() -> {
        ApplicationLauncher.main(new String[]{});
    });

    mainRunner.start();

    Thread.sleep(5000);

    assertEquals(Thread.State.WAITING, mainRunner.getState());
    mainRunner.interrupt();
}

Bwire 的回答是一个很好的方法,但我强烈建议不要 有人曾经在单元测试中使用 Thread.sleep() 来验证某些情况。不可能把握好时机:

  • 如果它太短,你会得到很多错误的结果(随机失败,是的)
  • 如果时间太长,随着时间的推移,您最终会创建非常缓慢的测试。不要小看这一点。

那么,答案是什么?任何时候你需要 "sleep" 来测试某些东西,而不是 "wait" 来确保它是真的(不断检查)。这样:

  • 只要条件为真,您的程序就会恢复——不会浪费时间。
  • 您可以将此 "wait" 的超时设置为非常大的值,以避免随机失败。

这是 Bware 自我回复的修改版...

public void testMain() throws Exception {
    Thread mainRunner = new Thread(() -> {
    ApplicationLauncher.main(new String[]{});
    });

    mainRunner.start();

    expectToBlock(mainRunner, 30, TimeUnit.SECONDS);

    mainRunner.interrupt();
}

private static void expectToBlock(Thread thread, long waitCount, TimeUnit waitUnits) {
    long start = System.currentTimeMillis();
    while (System.currentTimeMillis() - start < waitUnits.toMillis(waitCount)) {
        if (thread.getState() == Thread.State.WAITING) {
            return;
        }
        Thread.sleep(50); // Don't hog the CPU
    }
    Assert.fail("Timed out while waiting for thread to block");
}