title: Smart way to ensure Spring context stays alive during ThreadPoolTaskExecutor testing
body: <p>We're trying to implement a sort of ensurance between multi-threaded part of our application and the database access so that DB would not be hit with too many threads (customer requirement) and at the same time keep other parts of the system fully utilized with necessary amount of threads.</p>
  
  <p>Design seems to work of (spring batch partitioning + handling data access with a ThreadPoolTaskExecutor) but the issues is with testing the design (based on <a href="http://helenaedelson.com/?p=432" rel="nofollow">http://helenaedelson.com/?p=432</a>).</p>
  
  <p>For now I've had to add Thread.sleep(4000) into to my unit test to make sure that Spring context is not killed off from under the test before the spawned extra threads have a change to finish their work and give return values back to the main thread.</p>
  
  <p>Would anyone have some better ideas on how to make this test implementastion smarter?</p>
  
  <p>tester:</p>
  
  <pre><code>@RunWith(SpringJUnit4ClassRunner.class)
  @ContextConfiguration({ "classpath:partitionJdbcJob.xml" })
  @DirtiesContext(classMode = ClassMode.AFTER_CLASS)
  public class TaskTests {
  protected static final Logger logger = LoggerFactory.getLogger(TaskTests.class);
  
  @Autowired
  private OrderServiceImpl orderService;
  
  @Test
  public void testExecution() {
      logger.info("Starting execution thread...");
  
      for (int i = 0; i &lt; 8; i++) {
          orderService.dispatch();
      }
  
      try {
          // So that spring context is not destroyed from under the multi-threaded runnables
          Thread.sleep(4000);
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>test service:</p>
  
  <pre><code>@Service("orderServiceImpl")
  public class OrderServiceImpl {
  protected static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);
  
  @Resource(name = "beanTaskExecutor")
  private TaskExecutor taskExecutor;
  // private AsyncTaskExecutor taskExecutor;
  
  CompletionService completionService;
  
  @Autowired
  public void OrderServiceImpl(DataSource dataSource) {
      completionService = new ExecutorCompletionService(taskExecutor);
  }
  
  public void dispatch(final RetailPriceOptimization order) {
      logger.info("Starting dispatch execution...");
  
      if (this.taskExecutor != null) {
          logger.info("taskExecutor found...");
          this.taskExecutor.execute(new Runnable() {
              public void run() {
                  withExecutor(order);
              }
          });
      }
  
      try {
          Object future1 = completionService.take().get();
          Object future2 = completionService.take().get();
      } catch (InterruptedException e) {
          e.printStackTrace();
      } catch (ExecutionException e) {
          e.printStackTrace();
      }
      logger.info("Completed dispatch execution...");
  }
  
  private void withExecutor(final RetailPriceOptimization order) {
      logger.info("Starting withExecutor execution...");
  
      Object result1 = completionService.submit(new Callable&lt;String&gt;() {
          public String call() {
              return findById("0000dd2gsl1u1546");
          }
      });
      Object result2 = completionService.submit(new Callable() {
          public Object call() {
              return orderDao.find(new Long("16"));
          }
      });
  }
  </code></pre>
  
  <p>}</p>