2016-05-24 5 views
1

Я писал свой собственный модульный тест для своего модуля springxd (однако, я не планировал использовать xd.test и xd.dirt).set channel for LoggingHandler

Это процессорный модуль, что я сделал для проверки:

настроить контекст:

ctx = new ClassPathXmlApplicationContext("config/spring-module.xml"); 

получить inputDirectChannl и send(Message)

input = ctx.getBean("input", DirectChannel.class); 

input.send(msg); 

но для DirectChannel , Я должен предоставить ему subscriber, поэтому я решил написать LoggingHandlerBean к ouputDirectChannel, это он:

@Bean 
public LoggingHandler outputLogging(){ 
    LoggingHandler lh = new LoggingHandler("INFO"); 
    lh.setLoggerName("output-logging"); 
    lh.setShouldLogFullMessage(true); 
    return lh; 
} 

Но моя проблема: мне нужно loggingHandler быть абонентом output канала. Поэтому мне нужно как-то настроить его с помощью output. Я получил решение, как:

@Bean 
@ServiceActivator(inputChannel = "output") 
public LoggingHandler outputLogging(){ 
    LoggingHandler lh = new LoggingHandler("INFO"); 
    lh.setLoggerName("output-logging"); 
    lh.setShouldLogFullMessage(true); 
    return lh; 
} 

Но тем не менее существует еще Exception для:

org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'org[email protected]76b0bfab.output'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers 
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:81) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:442) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:392) 
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115) 
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45) 
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105) 
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:231) 
at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:154) 
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:102) 
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:105) 
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127) 
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116) 
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:147) 
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:120) 
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:442) 
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:392) 
at com.example.test.TestAll.allTest(TestAll.java:58) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
at java.lang.reflect.Method.invoke(Unknown Source) 
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) 
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 
Caused by: org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers 
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:153) 
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:120) 
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77) 
... 42 more 

Итак, мой вопрос:

Мне нужно настроить модуль либо с xml или делать с annotation, я не могу использовать их оба?

Если я могу, есть ли решение не использовать @ServiceActivator(inputChannel = "output"), это выглядит следующим образом:

<int:service-activator input-channel="input" method="trans" output-channel="output"> 
    <bean class="com.example.LoggingHandler" init-method="init" destroy-method="destroy"> 
... 
    </bean> 
</int:service-activator> 

, который на самом деле я не нужен сервис-активатор.

Спасибо!

[обновлено]

@Configuration 
@EnableIntegration 
public class TestAll { 

    ConfigurableApplicationContext ctx; 
    DirectChannel input; 
    DirectChannel output; 
    Logger logger = Logger.getLogger(TestAll.class); 
    //you have to configure this before you run, point this to the file path in the main/resources 
    String folderPath = "C:\\path\\to\\samples"; 

    @Before 
    public void setUp(){ 
     ctx = new ClassPathXmlApplicationContext("config/spring-module.xml"); 
     input = ctx.getBean("input", DirectChannel.class); 
     output = ctx.getBean("output", DirectChannel.class); 
     logger.setLevel(Level.ALL); 
     //ctx.addBeanFactoryPostProcessor(beanFactoryPostProcessor); 
    } 

    @Test 
    public void allTest(){ 
     Message<?> msg = composeMsg(); 
     input.send(msg); 
     logger.debug(output.isLoggingEnabled()); 
    } 

    @Bean 
    @ServiceActivator(inputChannel = "output") 
    public LoggingHandler outputLogging(){ 
     LoggingHandler lh = new LoggingHandler("INFO"); 
     lh.setLoggerName("output-logging"); 
     lh.setShouldLogFullMessage(true); 
     return lh; 
    } 

    public Message<?> composeMsg(){ 
    ... 
     return MessageBuilder.withPayload(msgPayload).copyHeaders(msgHeader).build(); 
    } 

    @After 
    public void tearDown(){ 
     ctx.close(); 
    } 
} 

ответ

2

Поскольку тест-случае я думаю, что вы идете правильным путем просто импортировать реальный модуль конфигурации и обеспечить некоторое тестирование сбрую, чтобы сделать его работу и закончить задачу.

И я даже думаю, что вы идете правильно с этой конфигурацией @ServiceActivator.

Только проблема, которую вам не хватает @EnableIntegration вместе с @Configuration.

С другой стороны, мне лучше сделать @BridgeFrom("output") на QueueChannel@Bean до assert. Но вам все равно нужно @EnableIntegration.

UPDATE

OK. Спасибо за обновленный код. Теперь я вижу.Проблема в том, что ваш класс TestAll@Configuration не зарегистрирован в ApplicationContext. Поэтому никто не будет обрабатывать @EnableIntegration и зарегистрировать LoggingHandler@Bean и так далее.

Попробуйте один:

@ContextConfiguration 
@RunWith(SpringJUnit4ClassRunner.class) 
@DirtiesContext 
public class TestAll { 

    @Autowired 
    @Qualifier("input") 
    private MessageChannel inputChannel; 

    @Autowired 
    private PollableChannel resultChannel; 

    @Test 
    public void allTest(){ 
     Message<?> msg = composeMsg(); 
     input.send(msg); 
     Message<?> result = resultChannel.receive(10000); 
     assertNotNull(result); 
     // Other asserts 
    } 

    @Configuration 
    @EnableIntegration 
    @ImportResource("classpath:config/spring-module.xml") 
    public static class ContextConfiguration { 

     @BridgeFrom("output") 
     public PollableChannel resultChannel() { 
      return new QueueChannel(); 
     } 
    } 

} 
+0

благодаря Артернам, я думаю, я буду попробовать '@ BridgeForm'. Но на самом деле у меня есть оба параметра @ @ EnableIntegration и '@ Configuration', аннотированные для моего тестового класса. Я также собираюсь добавить 'bean' во время выполнения. в любом случае, спасибо за вашу работу. и я обновляю вопрос с помощью своего кода, надеюсь, что это поможет вам найти, что не так с моим кодом. – cinqS

+1

Пожалуйста, см. Обновление в моем ответе. –