3

I have some Camel blueprint unit tests running against a camel route. The route is a simple camel route that pulls messages from an activemq queue and then sends to another queue. I'm using an osgi service to expose the amq component I'm sending and receiving from.

<reference id="activemq-in" filter="(osgi.jndi.service.name=amq/in)" interface="org.apache.camel.Component" />

  <camelContext>
    <route>
      <from uri="activemq-in:queue:some.queue" />
      ...
      <to uri="activemq-in:queue:some.other.queue" />
    </route>
  </camelContext>

In my unit test, I'm stubbing out the amq component with something else however whenever I run my unit tests they always hang on waiting for the activemq dependencies for about 30 seconds before it gives up and the unit test runs successfully.

INFO BlueprintContainerImpl - Bundle UnitTest/1.0.0 is waiting for dependencies [(&(osgi.jndi.service.name=amq/in)(objectClass=org.apache.camel.Component))]

Is there any way I can have Camel blueprint testing skip the waiting for dependencies stage?

EDIT:

Sample blank unit test that will just load the blueprint, wait for 30 seconds for the osgi service that doesn't exist, then give up and pass:

public class CamelTest extends CamelBlueprintTestSupport {

    // Loads the blueprint for the unit test
    @Override
    protected String getBlueprintDescriptor() {
         return "OSGI-INF/blueprint/blueprint.xml";
    }

    // configures the osgi service to use the embedded amq broker instead of the osgi resource
    @Override
    protected BundleContext createBundleContext() throws Exception {
        BundleContext bundleContext = super.createBundleContext();
        ActiveMQComponent activeMQComponent = new ActiveMQComponent();
        activeMQComponent.setBrokerURL("vm://amq");

        Properties inboundProperties = new Properties();
        inboundProperties.setProperty("osgi.jndi.service.name", "amq/in");
        bundleContext.registerService("org.apache.camel.Component", activeMQComponent, (Dictionary) inboundProperties);

         return bundleContext;
    }

    @Test
    public void blankTest() {
    }
}
Kenster
  • 23,465
  • 21
  • 80
  • 106
David
  • 579
  • 1
  • 5
  • 20
  • Do you use the method `assertMockEndpointsSatisfied()` in your test? Would be good if you can put a simple junit sample in your question. – рüффп Jun 09 '16 at 12:28
  • The unit test itself doesn't really matter since CamelBlueprintTestSupport tries to load the blueprint before running any unit tests. I've modified my question to include a blank unit test that still will wait for 30 seconds for the osgi service. – David Jun 10 '16 at 19:15

2 Answers2

0

If the service is not required for the unit test, then, you can create a fake blueprint/spring.xml file for your tests.. Except in this one, you don't start the service on start up. You have to refer to it in your test and can also choose not to start the normal bundle:

>   @Override   protected String getBundleFilter() {
>     // don't want the normal marc21import bundle to start as it causes conflict to our test
>     return "(!(Bundle-SymbolicName=<bundle_name>))";   }
> 
>   @Override   protected String getBlueprintDescriptor() {
>     return "blueprint/fake_blueprint.xml";   }
Souciance Eqdam Rashti
  • 3,143
  • 3
  • 15
  • 31
  • I can see how this would work but it would involve me maintain 2 copies of the same blueprint.xml. Doing so would be even more of a hassel than simply waiting for the service to time out. – David Jun 13 '16 at 19:12
  • Yes, but normally you keep the second copy in your test folder if you use maven and refer to it so it is not that much of a hassle. Besides, don't you get time out exception from the logs? This would remove that as well. – Souciance Eqdam Rashti Jun 14 '16 at 06:54
0

Yes, there is a way to handle this issue( I have gone through this annoying waiting for dependency stuff with blueprint unit testing). How I handle this issue ? Is by organising the bean definitions in its own files.

For example,

I keep bean declarations for CXF/JPA in its own bean-context.xml like , jpa-context.xml / cxf-context.xml.

And obviously, in my unit test case blueprint file I won't load these jpa/cxf bean contexts.

In this approach the routes also needs to be organised, You need to design the routes in such a way that, routes with these external integrations are kept in a separate light weight gateway routes. Keep all these gateway routes in a separate route context files. And don't load them in your blueprint unit test cases.

Lucky that we don't need to explicitly import files in blueprint. !

Why this approach ?

  1. I don't use unit test cases for testing external integrations(You will anyway do integration testing), I keep it mainly for testing my routing logic, transformations & business rules.

  2. You don't have to maintain 2 different beans-context files for testing & main.

Guess it helps !

Sample file structure:

bean-context.xml(in scope for unit testing)
cxf-context.xml(not required to include in unit testing)
jpa-context.xml(not required to include in unit testing)
gateway-routes.xml(not required to include in unit testing)
business-routes.xml(in scope for unit testing)

This way you won't see 'is waiting for dependencies' for cxf

Note: Also make sure to remove the unused xml namespace declarations in each of the xml files.

gnanagurus
  • 883
  • 1
  • 12
  • 29