Workaround to Multi Threaded Testing

DZone 's Guide to

Workaround to Multi Threaded Testing

· Java Zone ·
Free Resource

Since it has been introduced in JDK 1.5, I have loved the Executor abstraction over multi threaded execution. Basically you define tasks, implementing Runnable or Callable interfaces, and you submit those tasks to an Executor implementation. It's the Executor who knows how the tasks must be processed: scheduled at a certain time, enqueued in a separate single thread or using a thread pool. Different instances of Executor can be obtained through the Executors class.
In this way, the logic of your program is not dependant on how the multi threading needs to be implemented: you can think of tasks and executors, and you can choose, at a later time, how those tasks need to be processed. It's also possible to discover the status of a task: by taking a look at the Future.

Another advantage that I like is the fact that you can remove the issue of the multi threading during the tests. Testing multithreaded code is quite hard, because at the time you want to verify your assertions, the parallel threads may not yet be ready, so you have to play with the sleep(), join(), wait() and notify() methods, producing sometimes unreliable tests.

So, wouldn't it be wonderful if, just for testing, you could remove the complexity of the background execution? After all, we know that Executors work beautifully and we don't need actually to verify them.
In fact, as the Javadocs say

However, the Executor interface does not strictly require that execution be asynchronous. In the simplest case, an executor can run the submitted task immediately in the caller's thread:

class DirectExecutor implements Executor {
public void execute(Runnable r) {

Following the DIP principle, you can pass the above DirectExecutor to the class you want to test - I usually do it in the constructor - and, during the tests you have worked around the fact that something, in the real world would happen in background. You can, in other words, flatten the multiple threads in a single thread.


String message = "hello world!";
Executor executor = new DirectExecutor();
Chat chat = new Chat(executor);
// suppose that the sendMessage sends messages in background (async)
assertEqual(message, chatServer.lastMessageReceived());

Once we've used a DirectExecutor, we know that when we call sendMessage(), the execution of the logic behind it will now be synchronous. Then, the assertion at the next line can evaluate the result without waiting for the "background" process to complete. No sleeps and no thread coordination needed anymore.

The DirectExecutor as listed in the Javadocs can be improved to be more effective for testing purposes. For example, with Mockito you can implement a direct executor with a Mock Object that can also be queried to verify how the class under test interact with it.

// on the base test class (MockitoTestBase)
public void before() {

protected void implementAsDirectExecutor(ExecutorService executor) {
doAnswer(new Answer<Object>() {
public Object answer(InvocationOnMock invocation)
throws Exception {
Object[] args = invocation.getArguments();
Runnable runnable = (Runnable)args[0];
return null;

// on the subclass

@Mock private ExecutorService executor;

public void setUp() {

public void testChat() {
String message = "hello world!";
Chat chat = new Chat(executor);
// suppose that sendMessage sends messages in background (async)
// verify that the submit method has been invoked
Mockito.verify(executor, times(1)).sumit(...);
assertEqual(message, chatServer.lastMessageReceived());

In the above example I used an ExecutorService, which is a sub-interface of Executor, and provides additional features (like shutting down the executor and being able to reject tasks). But subsantially it's more or less the same.

Once we've tested that our class works fine with an instance of a DirectExecutor, we may assume that substituting it with a different one, our code will reasonably behave correctly. Of course, you still have to keep in mind that the task will be executed in the background and understand if you really covered your use case fully.

From http://en.newinstance.it/2010/09/07/workaround-to-multi-threaded-testing/


Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}