如何使用 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");
}
我有一个 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");
}