ferrisbueller
ferrisbueller

Reputation: 63

Camel @BeanInject doesn't work in Blueprint-Test

I'm trying to use CamelBlueprintTestSupport in order to test a camel route applying a number of beans. In the production code the beans are defined in a separate blueprint XML. In the test class I overwrite the addServicesOnStartup method just like documented. My unit test class looks like this:

public class MyUnit_Test extends CamelBlueprintTestSupport {

  @Override
  protected String getBlueprintDescriptor() {
    return "/OSGI-INF/blueprint/camel-routes.xml";
  }

  @Override
  protected void addServicesOnStartup(Map<String, KeyValueHolder<Object, Dictionary>> services) {    
    services.put("beanA", asService(new BeanA(), null, null));
    services.put("beanB", asService(new BeanB(), null, null));
  }

  @EndpointInject(uri = "mock:endpointMock")
  private MockEndpoint endpointMoc;

  @Test
  public void test_myRoute() throws Exception {
    (test code)
  }
}

One bean (BeanA) is referenced in the route:

<camelContext>
  <route>
    ...
    <bean ref="beanA" method="myMethod" />
    ...
  </route>
</camelContext>

This one needs access to another bean (BeanB). I use the @BeanInject annotation inide BeanA for this:

public class BeanA {

  @BeanInject("beanB")
  private BeanB beanB;

  public void myMethod(Exchange exchange) {
    beanB.getSomething();
  ...
}

In production the dependency injection works well.

Problem in unit test

In the unit test BeanA can be referenced by the route. But the injection of BeanB inside BeanA seems not to work. I receive NPE in BeanA.myMethod() when the code tries to access beanB.

It seems that the dependency injection only works for the routes in the blueprint XML but not recursively for the injected beans themselves.

Attempts

Upvotes: 2

Views: 1695

Answers (1)

smarquis
smarquis

Reputation: 540

Yes this does not work like this. My understanding it that stuff in the service registry is not like beans in the blueprint context.

Camel will try to autowire its beans from the context, using the (Camel, not blueprint) annotation @InjectBean. But Camel won't fiddle with stuff in the service registry; those are ready-made object to be used as-is or via proxies.

So you can either:

  • consider beanA as a service; then you prepare it fully (manually inject beanB into it) and add it to the service registry;
  • put beanA and beanB in the blueprint context (as you do in production code) by modifying your blueprint.xml for this purpose. (I understand that you may not want to do that though.)

What we would need would be a CamelBlueprintTestSupport that would consider multiple Blueprint contexts but this is not available to my knowledge. Indeed, there is no possibility to import contexts in Blueprint (contrary to Spring.)

Upvotes: 3

Related Questions