Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unit test that ExecutorService spawns new thread for task?

How does one unit test that a new thread was spawned for a Runnable task when using an ExecutorService?

Basically, I have a static thread pool for my application.

public static final ExecutorService executorService = Executors.newCachedThreadPool();

I'd like to use this thread pool for the my unit tests, rather than mocking one out or injecting a new thread pool, since different thread pools can dramatically alter the behavior of my application (fixed vs. cached vs. scheduled, etc); I want to ensure that I test the application's behavior with its run-time thread pool.

Cached thread pool seems to work best for me. The problem is that since it's static and the threads are cached for 60 seconds, only the first test will actually spawn a new thread in the pool, while subsequent tests reuse that thread.

Unit test code:

public void testDoCallExecutesTaskInAnotherThread() {    
    final Client client = this.createClient();
    final ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) client.getExecutorService(); // gets the static thread pool
    final int initPoolSize = threadPoolExecutor.getPoolSize();
    final Response response = client.doCall();
    Assert.assertEquals(initPoolSize + 1, threadPoolExecutor.getPoolSize());
}

Advice on how to get this working, or another approach altogether would be appreciated.

like image 296
Ben Simmons Avatar asked Nov 03 '09 19:11

Ben Simmons


People also ask

What method do you call to run a task on a worker thread using an ExecutorService?

We use the Executors. newSingleThreadExecutor() method to create an ExecutorService that uses a single worker thread for executing tasks. If a task is submitted for execution and the thread is currently busy executing another task, then the new task will wait in a queue until the thread is free to execute it.

How do you test threads?

To test multi-thread functionality, let the multiple instances of the application or program to be tested be active at the same time. Run the multi-thread program on different hardware. Thread testing is a form of session testing for which sessions are formed of threads.

Which are used to delegate tasks for execution to an ExecutorService?

We can assign tasks to the ExecutorService using several methods including execute(), which is inherited from the Executor interface, and also submit(), invokeAny() and invokeAll().

What is ExecutorService multithreading?

The ExecutorService helps in maintaining a pool of threads and assigns them tasks. It also provides the facility to queue up tasks until there is a free thread available if the number of tasks is more than the threads available.


1 Answers

Mock the ThreadFactory:

  ThreadFactory mock = new CustomObservableThreadFactory();
  ExecutorService executorService = Executors.newCachedThreadPool(mock);
  1. Inject the ExecutorService into the class under test as usual
  2. But use a custom ThreadFactory for creating the cached ThreadPool: The ThreadFactory will be called whenever a new Thread is to be called. You can then trace these instantiations as you like, e.g.with a listener or counter.
like image 161
mhaller Avatar answered Nov 15 '22 21:11

mhaller