![](/img/trans.png)
[英]Code running fine in debug mode, but stops when run normally (eclipse)
[英]Unit test succeeds in debug mode but fails when running it normally
为什么我的单元测试在调试模式下成功,但是在正常运行时失败?
public class ExecutorServiceTest extends MockitoTestCase{
private int numThreads;
private ExecutorService pool;
private volatile boolean interruptedBitSet;
@Override
public void setUp() {
numThreads = 5;
pool = Executors.newFixedThreadPool(numThreads);
}
class TaskChecksForInterruptedBit implements Callable<String> {
@Override
public String call() throws Exception {
interruptedBitSet = false;
while (!Thread.currentThread().isInterrupted()) {
}
interruptedBitSet = Thread.currentThread().isInterrupted();
return "blah";
}
}
public void testCancelSetsInterruptedBitInCallable() throws Exception {
interruptedBitSet = false;
final Future<String> future =
pool.submit(new TaskChecksForInterruptedBit());
final boolean wasJustCancelled = future.cancel(true);
assertTrue(wasJustCancelled);
// Give time for the thread to notice the interrupted bit and set the flag
Thread.sleep(5000);
// This succeeds when stepping through w/ a debugger, but fails when running
// the test straight. WHY?
assertTrue(interruptedBitSet);
assertTrue(future.isDone());
assertTrue(future.isCancelled());
}
}
原因几乎可以肯定是,调试器中的断点将暂停主线程,但不暂停任何后台线程-ExecutorService中的那些后台线程。 在Eclipse中调试时,您可以更改断点以暂停所有线程,而不仅仅是主要线程。
当不调试任务提交和立即取消时,是如此之快,以至于您在任务运行一次之前就将其取消。 尝试在这些行之间添加睡眠延迟:
final Future<String> future = pool.submit(new TaskChecksForInterruptedBit());
Thread.sleep(1000);
final boolean wasJustCancelled = future.cancel(true);
我知道这很旧,但是我遇到了同样的问题。 我的问题是我有一个IEnumerable ,我正在枚举并检查输出。
运行单元测试时, IEnumerable返回的调试顺序与其他顺序不同。 这就是IEnumerable的本质,只需添加一个OrderBy子句即可解决我的问题。
我希望这对外面的人有所帮助,因为这可能会令人沮丧。
您必须确保任务实际开始运行。 它甚至有可能被取消。
public class ExecutorServiceTest {
private int numThreads;
private ExecutorService pool;
private volatile boolean interruptedBitSet;
private static final CountDownLatch latch = new CountDownLatch(1);
@Before
public void setUp() {
numThreads = 5;
pool = Executors.newFixedThreadPool(numThreads);
}
class TaskChecksForInterruptedBit implements Callable<String> {
@Override
public String call() throws Exception {
interruptedBitSet = false;
latch.countDown();
while (!Thread.currentThread().isInterrupted()) {
System.out.println(System.currentTimeMillis());
}
System.out.println("haha");
interruptedBitSet = Thread.currentThread().isInterrupted();
return "blah";
}
}
@Test
public void testCancelSetsInterruptedBitInCallable() throws Exception {
final Future<String> future =
pool.submit(new TaskChecksForInterruptedBit());
interruptedBitSet = false;
latch.await();
final boolean wasJustCancelled = future.cancel(true);
Assert.assertTrue(wasJustCancelled);
// Give time for the thread to notice the interrupted bit and set the flag
Thread.sleep(5000);
// This succeeds when stepping through w/ a debugger, but fails when running
// the test straight. WHY?
Assert.assertTrue(interruptedBitSet);
Assert.assertTrue(future.isDone());
Assert.assertTrue(future.isCancelled());
}
}
您应该在终止主线程之前检查所有线程是否都死了
private void shutdownExecutionService(ExecutorService executorService) {
if (executorService != null) {
try {
executorService.shutdown();
while (!executorService.awaitTermination(10, TimeUnit.HOURS)) {
logger.info("Awaiting completion of threads.");
}
} catch (final InterruptedException e) {
logger.error("Error while shutting down threadpool", e);
}
}
}
通过在线课程进行家庭作业时,我遇到了类似的问题。 我添加到构建路径的课程中的评分器程序使用了JUnit4,我的Eclipse版本将JUnit5添加到了任何新的测试用例中。 我创建了一个新的Java项目,并在没有评分器的情况下为测试用例添加了JUnit5,并将其修复了。 希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.