【问题标题】:How to fail JUnit test from another thread如何使来自另一个线程的 JUnit 测试失败
【发布时间】:2022-06-28 23:04:00
【问题描述】:

考虑以下测试代码:

@Test
public void test() throws InterruptedException {
    var latch = new CountDownLatch(1);

    Executors.newSingleThreadExecutor().execute(() -> {
        latch.countDown();
        Assert.fail("Doesn't fail the test");
    });

    latch.await();
}

打印异常,但通过了。

线程“pool-1-thread-1”java.lang.AssertionError 中的异常: 没有通过测试 org.junit.Assert.fail(Assert.java:89) 在 MyTest.lambda$test$0(MyTest.java:55) 在 java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) 在 java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) 在 java.base/java.lang.Thread.run(Thread.java:834)

我尝试设置自定义未捕获异常处理程序setUncaughtExceptionHandler((t, e) -> Assert.fail(e.getMessage())),但这没有帮助。

【问题讨论】:

  • 您能澄清一下您通过这种方式运行测试要达到的目的吗?我认为this answer 可能会有所帮助,尽管我不完全了解您想要达到的结果。

标签: java multithreading junit


【解决方案1】:

您可以使用两个线程都可以访问的外部状态来执行此操作。请注意latch.countDown();应该在更改状态后添加

    private volatile boolean failed  = false;
    
    @Test
    public void test() throws InterruptedException {
        var latch = new CountDownLatch(1);

        Executors.newSingleThreadExecutor().execute(() -> {
            failed = true;//or false depending on the use case
            latch.countDown();
            
        });

        latch.await();
        if(failed){
            Assert.fail("Doesn't fail the test");
        }
    }

【讨论】:

    【解决方案2】:

    您还可以使用 shutdown + awaitTermination 来确保所有任务都已完成,并使用 try-catch 和 AtomicBoolean 来断言没有“内部”引发 AssertionErrors。

    AtomicBoolean failed = new AtomicBoolean(false);
    ExecutorService executorService = Executors.newFixedThreadPool(PARALLEL_POOL_SIZE);
    
    // start tasks.. maybe in a loop to generate load..
    executorService.execute(() -> {
      try {
        // Test something
        // ..
        // Validate
        assertThat(actual, equalTo(EXPECTED));
      } catch (AssertionError e) {
        failed.set(true);
        throw e;
      }
    });
    
    executorService.shutdown();
    boolean terminatedInTime = executorService.awaitTermination(5, TimeUnit.SECONDS);
    assertTrue(terminatedInTime);
    assertFalse(failed.get());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-10
      • 2011-03-29
      • 2019-05-02
      • 2015-07-04
      相关资源
      最近更新 更多