apache-camel

Doing bean inject in camel test


I have a camel app which look something like below which has a route like below:-

from("direct:getMarketplaceOrders")
    .to("bean:orderHelper?method=getMarketplaceOrders");

The entry point of the code look something like below:

public class OrderMainApp {
    public static void main(String... args) throws Exception {
        OrderMainApp orderMainApp = new OrderMainApp();
        DefaultCamelContext camelContext = new DefaultCamelContext();
        ProducerTemplate producer = camelContext.createProducerTemplate();
        camelContext.setRegistry(orderMainApp.createRegistry(producer));
        camelContext.addRoutes(new OrderRouteBuilder(producer));
        camelContext.start();
    }

    protected JndiRegistry createRegistry(ProducerTemplate producer) throws Exception {
        JndiRegistry jndi = new JndiRegistry();
        OrderHelper orderHelper = new OrderHelper();
        orderHelper.setProducer(producer);
        jndi.bind("orderHelper", orderHelper);
        return jndi;
    }
}

In OrderRouteBuilder configure has routes like below:

//processor is a custom JSONProcessor extending Processor
from("jetty:http://localhost:8888/orchestratorservice")
    .process(processor);
from("direct:getMarketplaceOrders")
    .to("bean:orderHelper?method=getMarketplaceOrders");

My goal is to test the response I receive from bean:orderHelper?method=getMarketplaceOrders when I place a request on direct:getMarketplaceOrders

orderHelper.getMarketplaceOrders looks like below:-

public OrderResponse getMarketplaceOrders(GetMarketplaceOrdersRequest requestParam) throws Exception

My test class look something like below:

public class OrderMainAppTest extends CamelTestSupport {

    @Produce(uri = "direct:getMarketplaceOrders")
    protected ProducerTemplate template;

    @EndpointInject(uri = "bean:orderHelper?method=getMarketplaceOrders")
    protected MockEndpoint resultEndpoint;

    @Test
    public void testSendMatchingMessage() throws Exception {
    String expectedBody = "<matched/>";

    template.sendBody("{\"fromDateTime\": \"2016-01-11 10:12:13\"}");

    resultEndpoint.expectedBodiesReceived(expectedBody);

    resultEndpoint.assertIsSatisfied();
    }

    @Override
    protected RouteBuilder createRouteBuilder() {
        return new RouteBuilder() {
            @Override
            public void configure() {
                from("direct:getMarketplaceOrders")
                    .to("bean:orderHelper?method=getMarketplaceOrders");
            }
        };
    }
}

Whenever I am running the test I am getting the below exception:

java.lang.IllegalArgumentException: Invalid type:
    org.apache.camel.component.mock.MockEndpoint which cannot be injected via
    @EndpointInject/@Produce for: Endpoint[bean://orderHelper?method=getMarketplaceOrders]

I am guessing this is because I am not able to pass on OrderHelper to the camel test context. Can some one let me know how can I inject the bean in the mock result end point?

EDIT

I tried modifying my test class as follows:

    public class OrderMainAppTest extends CamelTestSupport {
    
        protected OrderHelper orderHelper = new OrderHelper();
    
        @Produce(uri = "direct:getMarketplaceOrders")
        protected ProducerTemplate template;
         
        @EndpointInject(uri = "mock:intercepted")
        MockEndpoint mockEndpoint;
    
        @Before
        public void preSetup() throws Exception {
            orderHelper.setProducer(template);
        };
    
        @Test
        public void testSendMatchingMessage() throws Exception {
    
            GetMarketplaceOrdersRequest request = new GetMarketplaceOrdersRequest();
            request.setFromDateTime("2016-01-11 10:12:13");
            request.setApikey("secret_key");
            request.setMethod("getMarketplaceOrders");
            request.setLimit(10);
            request.setOffset(2);
    
            template.sendBody(request);
            mockEndpoint.expectedBodiesReceived("{\"success\":\"false\"");
        }
    
        @Override
        protected RouteBuilder createRouteBuilder() {
            return new RouteBuilder() {
                @Override
                public void configure() {
                    interceptSendToEndpoint("bean:orderHelper?method=getMarketplaceOrders")
                        .to("mock:intercepted");
                    from("direct:getMarketplaceOrders")
                        .to("bean:orderHelper?method=getMarketplaceOrders");
                }
            };
        }
    
        @Override
        protected JndiRegistry createRegistry() throws Exception {
            return getRegistry();
        }
    
        protected JndiRegistry getRegistry() {
            JndiRegistry jndi = new JndiRegistry();
            jndi.bind("orderHelper", orderHelper);
            return jndi;
        }
    }

The above code is making the request correctly and is flowing through my app correctly. But I am not able to intercept the response of orderHelper.getMarketplaceOrders. The above code is intercepting only the request. I tried changing to template.requestBody(request). But still no luck.


Solution

  • By updating my createRouteBuilder as shown below. I am able to intercept the response and send it to a mock endpoint where I can do the assertion.

    @Override
    protected RouteBuilder createRouteBuilder() {
    return new RouteBuilder() {
        @Override
        public void configure() {
        from("direct:getMarketplaceOrders").to("bean:orderHelper?method=getMarketplaceOrders").onCompletion()
            .to("mock:intercepted");
        }
    };
    }