@Test
 public void roundRobinLoadBalancing() throws Exception {
   int numberOfMessages = 11;
   ConcurrentTaskExecutor taskExecutor =
       new ConcurrentTaskExecutor(
           Executors.newSingleThreadScheduledExecutor(new CustomizableThreadFactory("test-")));
   ExecutorChannel channel =
       new ExecutorChannel(taskExecutor, new RoundRobinLoadBalancingStrategy());
   CountDownLatch latch = new CountDownLatch(numberOfMessages);
   TestHandler handler1 = new TestHandler(latch);
   TestHandler handler2 = new TestHandler(latch);
   TestHandler handler3 = new TestHandler(latch);
   channel.subscribe(handler1);
   channel.subscribe(handler2);
   channel.subscribe(handler3);
   for (int i = 0; i < numberOfMessages; i++) {
     channel.send(new GenericMessage<String>("test-" + i));
   }
   latch.await(3000, TimeUnit.MILLISECONDS);
   assertEquals(0, latch.getCount());
   assertNotNull(handler1.thread);
   assertFalse(Thread.currentThread().equals(handler1.thread));
   assertTrue(handler1.thread.getName().startsWith("test-"));
   assertNotNull(handler2.thread);
   assertFalse(Thread.currentThread().equals(handler2.thread));
   assertTrue(handler2.thread.getName().startsWith("test-"));
   assertNotNull(handler3.thread);
   assertFalse(Thread.currentThread().equals(handler3.thread));
   assertTrue(handler3.thread.getName().startsWith("test-"));
   assertEquals(4, handler1.count.get());
   assertEquals(4, handler2.count.get());
   assertEquals(3, handler3.count.get());
 }
 @Test
 public void verifyDifferentThread() throws Exception {
   SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
   taskExecutor.setThreadNamePrefix("test-");
   ExecutorChannel channel = new ExecutorChannel(taskExecutor);
   CountDownLatch latch = new CountDownLatch(1);
   TestHandler handler = new TestHandler(latch);
   channel.subscribe(handler);
   channel.send(new GenericMessage<String>("test"));
   latch.await(1000, TimeUnit.MILLISECONDS);
   assertEquals(0, latch.getCount());
   assertNotNull(handler.thread);
   assertFalse(Thread.currentThread().equals(handler.thread));
   assertEquals("test-1", handler.thread.getName());
 }
  @Test
  public void interceptorWithModifiedMessage() {
    ExecutorChannel channel = new ExecutorChannel(new SyncTaskExecutor());
    channel.setBeanFactory(mock(BeanFactory.class));
    channel.afterPropertiesSet();

    MessageHandler handler = mock(MessageHandler.class);
    Message<?> expected = mock(Message.class);
    BeforeHandleInterceptor interceptor = new BeforeHandleInterceptor();
    interceptor.setMessageToReturn(expected);
    channel.addInterceptor(interceptor);
    channel.subscribe(handler);
    channel.send(new GenericMessage<Object>("foo"));
    verify(handler).handleMessage(expected);
    assertEquals(1, interceptor.getCounter().get());
    assertTrue(interceptor.wasAfterHandledInvoked());
  }
  @Test
  public void interceptorWithException() {
    ExecutorChannel channel = new ExecutorChannel(new SyncTaskExecutor());
    channel.setBeanFactory(mock(BeanFactory.class));
    channel.afterPropertiesSet();

    Message<Object> message = new GenericMessage<Object>("foo");

    MessageHandler handler = mock(MessageHandler.class);
    IllegalStateException expected = new IllegalStateException("Fake exception");
    willThrow(expected).given(handler).handleMessage(message);
    BeforeHandleInterceptor interceptor = new BeforeHandleInterceptor();
    channel.addInterceptor(interceptor);
    channel.subscribe(handler);
    try {
      channel.send(message);
    } catch (MessageDeliveryException actual) {
      assertSame(expected, actual.getCause());
    }
    verify(handler).handleMessage(message);
    assertEquals(1, interceptor.getCounter().get());
    assertTrue(interceptor.wasAfterHandledInvoked());
  }