Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write concurrent unit tests

Awaitility is a great tool to unit-test concurrent production code.

Question: Is there a tool to ease writing concurrent test code?

Suppose I wanted to test java.util.concurrent.LinkedBlockingQueue.

public class BlockingQueueTest {
    private LinkedBlockingQueue<String> out;

    @Before
    public void setUp() {
        out = new LinkedBlockingQueue<>();
    }

    @Test
    public void putThenGet() throws InterruptedException {
        // that's easy because it can be done in one thread
        out.put("Hello");

        String taken = out.take();

        assertThat(taken).isEqualTo("Hello");
    }

    @Test
    public void getBeforePut() throws InterruptedException {
        // that's more tricky because it can't be done with one thread
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.submit(() -> {
            Thread.sleep(100);
            out.put("Hello");
            return null;
        });
        executorService.shutdown();

        String taken = out.take();

        assertThat(taken).isEqualTo("Hello");
    }
}

getBeforePut() is no fun to code. Is there a way to make it less hard and more readable, like so?

@Test
public void getBeforePut2() throws InterruptedException {
    // Wanted: DSL for concurrent test-code
    Concurrently.sleep(100, TimeUnit.MILLISECONDS).andThen(() -> out.put("Hello"));

    String taken = out.take();

    assertThat(taken).isEqualTo("Hello");
}
like image 307
Frank Neblung Avatar asked Nov 28 '25 21:11

Frank Neblung


1 Answers

Using TestNG is the easiest way as for me:

 @Test(threadPoolSize = 10, invocationCount = 15, timeOut = 1000)
 public void testPut(){
     out.put("Hello");
 }

This test will run 15 times in 10 threads and should take no longer than 1000 ms.

Also you can create tests which depends on other test

@Test(dependsOnMethods = "testPut")
public void testGetAfterPut{
    String taken = out.take();

    assertThat(taken).isEqualTo("Hello");
}
like image 171
Sergii Bishyr Avatar answered Nov 30 '25 12:11

Sergii Bishyr



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!