Search code examples
javaspring-bootjunitapache-camelspring-camel

Unit Test Apache-Camel JmsReplyTo route flow


I have the following sample route flow, where I receive a jms message, built a webservice request and then respond to the JMSReplyTo with the webservice response:

    from("{{jms.input.queue}}).routeId("Receive JMS Message")
        .to("direct:start");


    from("direct:start").routeId("Build & Send Http Request")
            .bean(processRequest)
            .to("{{http.endpoint}}")
            .to("direct:processResponse");

    from("direct:processResponse").routeId("Build XML Response")
            .convertBodyTo(String.class)
            .bean(processResponse);

I have successfuly unit tested my processes, but now I want to unit test my route flow. Instead of having a EMS server running during tests, I have started from the second route:

  camelContext.getRouteDefinition("Build & Send Http Request").adviceWith(camelContext,
            new AdviceWithRouteBuilder() {
                @Override
                public void configure() throws Exception {
                    interceptSendToEndpoint("http://*")
                    .skipSendToOriginalEndpoint()
                    .setBody("Hello");
                }
            });

@Test
@DirtiesContext
public void RouteFlowTest() throws Exception{

    Map<String,Object> jmsHeaders = new HashMap<>();
    jmsHeaders.put("Auth","helloWorld");
    jmsHeaders.put("JMSReplyTo","sample");

    String jmsBody = "Help Me"
    incomingJmsRequestMessage.sendBodyAndHeaders("direct:start", jmsBody, jmsHeaders);

}

but now how to I assert the exchange after the processResponse bean has been executed?

Or is there a way to test from the first route and satisfy the JMSReplyTo without actually having a EMS server running?


Solution

  • As you are already weaving the route, you'd could add a propagation to a mock endpoint within your route advice such as:

    this.weaveAddLast().to("mock:done");
    

    which just adds a .to("mock:done") defintion to the end of your "Build & Send Http Request" route. From the given problem statement it is a bit unclear what .bean(processResponse); actually does. You could also add this mock endpoint propagation to the "Build XML Response" route in which case you'd need a further route advice definition.

    Next, you can either let Camel inject a mock endpoint via

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

    or define it manually inside your test via:

    MockEndpoint done = camelContext.getEndpoint("mock:done", MockEndpoint.class);
    

    This mock endpoint can be used to define certain expectations such that you'd expect one message to be received by that endpoint

    done.expectedMessageCount(1);
    ...
    // invoke your route here
    template.sendBody(...);
    ...
    done.assertIsSatisfied();
    

    You can also access the exchanges received by this endpoint directly via the following direction and perform further assertions on it:

    Exchange exchange = done.getExchanges().get(0);
    ...
    

    If you'r using Camel on top of Spring (Boot) you might also read through how to test Camel with Spring enabled