8

I am new to Spring Integration. I have ActiveMQ with say a 'responseQ'. So when a message arrives on 'responseQ' -> painResponseChannel -> transformer -> processResponseChannel -> beanProcessing. I have following setup:

    <jms:message-driven-channel-adapter  extract-payload="true"
                                     channel="painResponseChannel"
                                     connection-factory="connectionFactory"
                                     destination-name="responseQ"/>

    <integration:channel id="painResponseChannel" />

    <integration-xml:unmarshalling-transformer
        id="defaultUnmarshaller"
        input-channel="painResponseChannel"
        output-channel="processResponseChannel"
        unmarshaller="marshaller"/>

    <integration:channel id="processResponseChannel" />

    <integration:service-activator
        input-channel="processResponseChannel"
        ref="processResponseActivator"/>

    <bean id="processResponseActivator" class="com.messaging.processor.PainResponseProcessor"/>


    <bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
      <property name="classesToBeBound">
        <list>
            <value>com.domain.pain.Document</value>
        </list>
      </property>
    </bean>

So my question is HOW CAN I TEST THIS END TO END? How can I assert the output of the transformer or assert whats on the channel? I have tried but failed... Hope someone can help.

Thanks in advance. GM

I was testing like this: In my test-context created a outbound-channel-adapter which initiates putting a message on the activeMQ using the testJmsQueue channel. And also created a BRIDGE for the processResponseChannel -> testChannel. I was expecting the receive() method to give me something back. But I think the issue is that it too fast and by the time it gets to the receive() method the pipeline has ended.

The test-context looks like this:

<integration:bridge input-channel="processResponseChannel" output-channel="testChannel"/>

<jms:outbound-channel-adapter id="jmsOut" destination-name="responseQ" channel="testJmsQueue"/>

<integration:channel id="testJmsQueue"/>

<integration:channel id="testChannel">
    <integration:queue/>
</integration:channel>

and then in the unit test I have this:

@ContextConfiguration(locations = "classpath*:PainResponseTest-context.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class PainResponseTest {

private String painResponseXML;

@Autowired
MessageChannel testJmsQueue;
@Autowired
QueueChannel testChannel;

@Before
public void setup() throws Exception {

    ClassPathResource cpr = new ClassPathResource("painResponse.xml");
    InputStream is = cpr.getInputStream();
    StringWriter writer = new StringWriter();
    IOUtils.copy(is, writer, "UTF-8");
    painResponseXML = writer.toString();
}

@Test
@SuppressWarnings("unchecked")
public void shouldDoSomething() throws InterruptedException {

    testJmsQueue.send(MessageBuilder.withPayload(painResponseXML).build());

    Message<String> reply = (Message<String>) testChannel.receive(0);
    Assert.assertNotNull("reply should not be null", reply);
    String out = reply.getPayload();
    System.out.println(out);
}
}

==================== TEST OUTPUT =====================
java.lang.AssertionError: reply should not be null

Getting reply as null.

Kowser
  • 8,123
  • 7
  • 40
  • 63
user2279337
  • 691
  • 5
  • 13
  • 26
  • See the [Basic](https://github.com/garyrussell/spring-integration-samples/tree/master/basic/testing-examples) and [Advanced](https://github.com/garyrussell/spring-integration-samples/tree/master/advanced/advanced-testing-examples) Testing Samples. Also, [Spring Integration in Action](http://www.manning.com/fisher/) has a chapter on testing, which happens to be a sample chapter at [Manning](http://www.manning.com/fisher/). – Gary Russell Apr 25 '13 at 16:40
  • Gary, thanks for the reply. Please see my updated question above. I have included test-context and unit test that I am using. Further advise or code sample would be useful. – user2279337 Apr 26 '13 at 08:16
  • You are not waiting long enough, use `Message reply = (Message) testChannel.receive(2000);`. Also you have a problem in that you have two subscribers on `processResponseChannel` - the service activator and your bridge. Declare the channel as a ` so both get a copy. A regular channel with multiple subscribers will round-robin. As always, turning on DEBUG logging will give you a thorough message trace. – Gary Russell Apr 26 '13 at 12:40
  • Gary, thank you you are a star. I changed both the channels to and the tests work now. Thanks again. – user2279337 Apr 27 '13 at 21:25
  • 1
    I recommend looking specifically at the ExternalGatewaySubstitutionTests in https://github.com/spring-projects/spring-integration-samples/tree/master/basic/testing-examples because it shows how to structure the main config xml to allow for stubbing the external channels. – David W Jan 27 '17 at 15:27

1 Answers1

1

For end-to-end testing, you can do the following;

  • use activemq in an embedded configuration to send the JMS message
  • inject a channelinterceptor on the processResponseChannel
  • enable DEBUG level - Spring Integration gives very good and helpful logs tracing messages in and out of channels and service activators
Petr Kozelka
  • 7,670
  • 2
  • 29
  • 44
incomplete-co.de
  • 2,137
  • 18
  • 23
  • Thanks for the reply. Please see my updated question above. I have included test-context and unit test that I am using. Further advise or code sample would be useful. – user2279337 Apr 26 '13 at 08:17