【问题标题】:AssertThrows doesn't catch Exception while calling the method throws the same Exception调用方法时 AssertThrows 未捕获异常引发相同的异常
【发布时间】:2022-01-12 10:14:30
【问题描述】:

谁能向我解释为什么,在这种情况下,断言在调用方法时抛出异常似乎不起作用,因为“预计会抛出 it.exceptions.SemaphoreException,但没有抛出任何东西" 直接调用方法会引发同样的异常吗?

@Test
void concurrentBatchTest() {
    ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
    for(int i=0; i < 1; i++) {
        Runnable worker = new RProcess();
        executor.execute(worker);
    }
    executor.shutdown();
    while (!executor.isTerminated()) {
        // Assertion fails because nothing was thrown
        assertThrows(SemaphoreException.class, () -> drlScheduler.computeR());
        // Calling the method with the following line ends throwing SemaphoreException
        // drlScheduler.computeR();
    }
}

private class RProcess implements Runnable {
    @Override
    public void run() {
        drlScheduler.computeR();
    }
}

我可以使用 try-catch 块直接调用该方法来解决问题,但它不如断言要抛出的异常那么清楚。

考虑到 computeR() 是一种非常快速的方法,因此问题可能与断言要抛出的异常比直接调用方法慢的事实有关,在第一种情况下,当方法遇到信号量时信号量已经关闭,有没有人有证据证明我所说的或这种行为背后的真正原因?

【问题讨论】:

  • 直接调用时,是不是总是抛出那个异常?比如,你能在它抛出之前绕循环几次吗?
  • 它总是抛出异常,它做的第一条指令是检查Semaphore是on还是off,直接调用方法时总是发现它On。

标签: java multithreading testing


【解决方案1】:

我认为原因可能是由于异常是在不同的线程上引发的。

你创建一个runnable并用ExecutorService执行它的run方法,所以当worker调用dlrScheduler.computeR();远程线程抛出异常,而JUnit只能捕获主线程抛出的异常(这就解释了为什么您可以直接在concurrentBatchTest 方法中运行dlrScheduler.computeR(); 并断言抛出异常)。

请参阅this 答案以获取解决方案,希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 2011-07-19
    • 2014-07-09
    • 2021-12-26
    • 1970-01-01
    • 2015-10-14
    • 2012-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多