Announcement Announcement Module
No announcement yet.
Testing across processes Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Testing across processes

    Does spring provide a way to test between two process, each running in a separate VM? Say I have a service that is connected to the service bus via Spring integration. I would like to start up the service that responds to messages, then start the sender of those messages, both in their own vm. I know that I can mock services, and even provide for ways in which to start them in the same vm, but the true test would be to really have them tested side-by-side and coordinated.

    Is that readily possible? What approach have some of you taken to this problem?



  • #2
    It's possible using any of the channel adapters or gateways as outbound on one process and inbound on the other process. What protocol/shared-service do you want to use between them? For example, you can use TCP, UDP, HTTP, JMS, AMQP - or you could use the File system, RDBMS, or any of the other adapters.


    • #3
      More info

      Right now I'm transitioning to using spring integration by programming to interfaces in an existing system, and using spring to plug implementations for the services. The service I'm trying to test right now starts an xml-rpc server remotely, and I'm connecting with a test client. Xml-rpc is going to go away to be replaced with messaging, but now I'm proving that the interface separation has been successful.

      To make the transition, I need test cases that will validate the code before and after the switch, so I'd like to use some form of automated test case that is capable of loading and initializing the xml-rpc server in it's own vm, and my client test case in another. I'll complete a set of interactions between the two and shut them both down afterwards. Right now I'd have to start the xml-rpc server in a manual step prior to running my test case.



      • #4
        Why not use jetty or tomcat 7 server in embedded mode that will start the server programatically? Once you are done with your test you can also shut it down. Your test client can do this before and after you execute your tests.


        • #5
          Another technique I've used successfully is to put both jars on the classpatch and use a <bridge/> to connect them.

          For example, if app1 ends with


          and app2 begins with


          Structure your files such that the adapters can be skipped (e.g. using Spring 3.1 profiles, or putting them in a separate config file that is <import/>ed into the production code).

          Then, in your test case create a <bridge input-channel="lastChanApp1" outputChannel="firstChanApp2" />

          If you are using gateways you can bridge the reply channels too.

          There are some limitations with this technique, but it works in many cases.


          • #6
            Thanks for your input, guys. I think a combination of both ideas might play well. When I settle on a method, I'll update the thread. I think it is a common challenge faced by organizations serious about automated testing.


            • #7
              Can the bridge approach work in the case the channels are not the equivalent of DirectChannel. I have several JMS backed channels which I am using in the same application because I need to persist the messages and am having a hard time setting up the unit tests. It gets even more difficult when I have an integration workflow where output from one channel goes through a series of routers / splitters / aggregators. What is the best way to unit test in this scenario ? The samples mostly show bridges for unit testing since all the channels in question seem like a DirectChannel


              • #8
                One technique I have used is to put all JMS-related configs (adapters, jms-backed channels etc) in one config file (or Spring 3.1 profile) and replace jms-backed channels in tests with non-jms-backed channels. Something like this...

                <int:channel id="firstChannel" />
                <int:service-activator input-channel="firstChannel" output-channel="someChannel"/>
                <int:service-activator input-channel="someChannel" output-channel="outChannel"/>
                <int-stream:stdout-channel-adapter id="outChannel"/>
                <beans profile="production">
                	<int-jms:message-driven-channel-adapter channel="firstChannel"  ... />
                	<int-jms:channel id="someChannel" ... />
                <beans profile="testing">
                	<int:channel id="someChannel" />
                If you are not using Spring 3.1, you can achieve the equivalent by putting the jms stuff in one file and testing equivalents in another - in production <import/> the jms config, in testing <import/> the other.