0

Consider following test code:

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

It prints exception, but passes.

Exception in thread "pool-1-thread-1" java.lang.AssertionError: Doesn't fail the test at org.junit.Assert.fail(Assert.java:89) at MyTest.lambda$test$0(MyTest.java:55) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:834)

I have tried to set custom uncaught exception handler setUncaughtExceptionHandler((t, e) -> Assert.fail(e.getMessage())), but this didn't help.

Nolequen
  • 3,032
  • 6
  • 36
  • 55
  • Could you clarify what you are trying to accomplish with running tests this way? I think [this answer](https://stackoverflow.com/a/2248203/12092416) might help though I don't understand completely what result you want to achieve. – Sergei Nov 30 '21 at 17:13

2 Answers2

1

You can do this with an external state that both threads can access. Please note latch.countDown(); should be added after you changed the state

    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");
        }
    }
Liviu Stirb
  • 5,876
  • 3
  • 35
  • 40
0

You could also use shutdown + awaitTermination to make sure all tasks are finished and use a try-catch and an AtomicBoolean to assert no AssertionErrors were raised "inside".

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());
icyerasor
  • 4,973
  • 1
  • 43
  • 52