简体   繁体   English

单元测试在调试模式下成功,但是在正常运行时失败

[英]Unit test succeeds in debug mode but fails when running it normally

Why does my unit test succeed in debug mode but fail 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());
  }
}

The reason is almost certainly that your breakpoint in the debugger is halting the main thread but not any of the background threads - the ones in the ExecutorService. 原因几乎可以肯定是,调试器中的断点将暂停主线程,但不暂停任何后台线程-ExecutorService中的那些后台线程。 When debugging in eclipse you can change the breakpoint to halt all threads instead of just the main one. 在Eclipse中调试时,您可以更改断点以暂停所有线程,而不仅仅是主要线程。

When not debugging the submission of the task and the immediate cancellation are so quick that you are cancelling the task before it even runs once. 当不调试任务提交和立即取消时,是如此之快,以至于您在任务运行一次之前就将其取消。 Try adding a sleep delay between these lines: 尝试在这些行之间添加睡眠延迟:

final Future<String> future =  pool.submit(new TaskChecksForInterruptedBit());
Thread.sleep(1000);
final boolean wasJustCancelled = future.cancel(true);

I know this is old but I just had the same problem. 我知道这很旧,但是我遇到了同样的问题。 My issue was that I had an IEnumerable that I was enumerating and checking the output. 我的问题是我有一个IEnumerable ,我正在枚举并检查输出。

When running the Unit test, the IEnumerable was returning a different ordering that when debugging. 运行单元测试时, IEnumerable返回的调试顺序与其他顺序不同。 This is the nature of IEnumerable and simply adding an OrderBy clause solved my problem. 这就是IEnumerable的本质,只需添加一个OrderBy子句即可解决我的问题。

I hope this helps someone out there as it can be a frustrating problem to find. 我希望这对外面的人有所帮助,因为这可能会令人沮丧。

You have to make sure your task actually started running. 您必须确保任务实际开始运行。 It may get cancelled before it even has a chance. 它甚至有可能被取消。

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());
    }
}

You should check whether all the threads dies before terminating the main thread 您应该在终止主线程之前检查所有线程是否都死了

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);
        }
    }
}

I was having a similar issue while running a homework assignment from an online course. 通过在线课程进行家庭作业时,我遇到了类似的问题。 The grader program from the course which I added to the build path used JUnit4, my version of Eclipse added JUnit5 to any new test cases. 我添加到构建路径的课程中的评分器程序使用了JUnit4,我的Eclipse版本将JUnit5添加到了任何新的测试用例中。 I've created a new Java Project and added JUnit5 to the build bath for my test cases without the grader and it fixed it for me. 我创建了一个新的Java项目,并在没有评分器的情况下为测试用例添加了JUnit5,并将其修复了。 Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 代码在调试模式下可以正常运行,但是在正常运行时(Eclipse)会停止 - Code running fine in debug mode, but stops when run normally (eclipse) Java的未来。 它在调试模式下成功,但是当我正常运行时失败 - Java Future. It suceeds in debug mode but fails when i run it normally 正常运行代码时我无法执行sqlite语句,但在调试模式下它可以工作。 这怎么可能? - I can't execute sqlite statement when running code normally, but in debug mode it works. How is it possible? 为zxing运行单元测试失败 - Running the unit test for zxing fails 仅当通过Ant任务运行时,单元测试才会失败 - Unit test fails only when running from with Ant task 在调试模式下运行时元素是可点击的,但正常运行时会抛出 ElementClickInterceptedException - Element is clickable when ran in debug mode, but ran normally throws ElementClickInterceptedException UI在调试模式下按预期更新,但在正常运行时不执行任何操作 - UI updates as expected in debug mode, but does nothing when run normally 正常运行时代码无效,但在调试(eclipse)中工作 - Code not working when running normally, but working in debug (eclipse) JUnit 测试在运行模式下通过,但在调试模式下失败? - JUnit test passes in Run mode, but fails in debug mode? maven 1在运行测试时失败 - maven 1 fails when running test
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM