I am looking at improving a package that I believe not to be threadsafe when its input is shared between multiple worker threads. According to TDD principles, I should write so
There is nothing wrong with unit testing multi-threaded code if threading is the point of the code you're testing (think concurrent data structures). The general approach is to block the main test thread, perform assertions in separate threads, capturing and re-throwing any failed assertions in the main thread, else unblock the main test thread so the test can complete. It's pretty straightforward to do with ConcurrentUnit:
@Test
public void shouldDeliverMessage() throws Throwable {
final Waiter waiter = new Waiter();
messageBus.registerHandler(message -> {
// Called on separate thread
waiter.assertEquals(message, "foo");
// Unblocks the waiter.await call
waiter.resume();
};
messageBus.send("foo");
// Wait for resume() to be called
waiter.await(1000);
}
The key here is that any failed assertions in any thread will be re-thrown in the main thread by the waiter
, allowing the test to pass or fail as it should.