Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I properly use Mocks when testing Camel routes?

Tags:

apache-camel

I am trying to write a Camel test that checks to ensure a content based router is routing XML files correctly. Here are the enpoints and the route in my blueprint.xml:

<endpoint uri="activemq:queue:INPUTQUEUE" id="jms.queue.input" />
<endpoint uri="activemq:queue:QUEUE1" id="jms.queue.1" />
<endpoint uri="activemq:queue:QUEUE2" id="jms.queue.2" />

<route id="general-jms.to.specific-jms">
    <from ref="jms.queue.input" />
    <choice>
      <when>
        <xpath>//object-type = '1'</xpath>
        <log message="Sending message to queue: QUEUE1" />
        <to ref="jms.queue.1" />
      </when>
      <when>
        <xpath>//object-type = '2'</xpath>
        <log message="Sending message to queue: QUEUE2" />
        <to ref="jms.queue.2" />
      </when>
      <otherwise>
        <log message="No output was able to be determined based on the input." />
      </otherwise>
    </choice>
</route>

Right now, all I am trying to do is send in a sample source file that has an <object-type> of 1 and verify that is it routed to the correct queue (QUEUE1) and is the correct data (should just send the entire XML file to QUEUE1). Here is my test code:

public class RouteTest extends CamelBlueprintTestSupport {

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

    @Override
    public String isMockEndpointsAndSkip() {
        return "activemq:queue:QUEUE1";
    }

    @Test
    public void testQueue1Route() throws Exception {

        getMockEndpoint("mock:activemq:queue:QUEUE1").expectedBodiesReceived(context.getTypeConverter().convertTo(String.class, new File("src/test/resources/queue1-test.xml")));

        template.sendBody("activemq:queue:INPUTQUEUE", context.getTypeConverter().convertTo(String.class, new File("src/test/resources/queue1-test.xml")));

        assertMockEndpointsSatisfied();
    }
}

When I run this test, I see the log message that I put in the route definition that says it is sending it to QUEUE1, but the JUnit test fails with this error message: java.lang.AssertionError: mock://activemq:queue:QUEUE1 Received message count. Expected: <1> but was: <0>.

Can someone help me understand what I am doing wrong?

My understanding is that Camel will automatically mock the QUEUE1 endpoint since I overrode the isMockEndpointsAndSkip() and provided the QUEUE1 endpoint uri. I thought this meant I should be able to use that endpoint in the getMockEnpoint() method just by appending "mock:" to the beginning of the uri. Then I should have a mocked endpoint of which I can set expections on (i.e. that is has to have the input file).

If I am unclear on something please let me know and any help is greatly appreciated!

like image 247
jonjon1123 Avatar asked Feb 23 '15 19:02

jonjon1123


1 Answers

The solution is to use CamelTestSupport.replaceRouteFromWith.

This method is completely lacking any documentation, but it works for me when invoking it like this:

public class FooTest extends CamelTestSupport {

    @Override
    public void setUp() throws Exception {
        replaceRouteFromWith("route-id", "direct:route-input-replaced");
        super.setUp();
    }

    // other stuff ...

}

This will also prevent the starting of the original consumer of the from destination of the route. For example that means it isn't necessary anymore to have a activemq instance running when a route with an activemq consumer is to be tested.

like image 91
SpaceTrucker Avatar answered Sep 18 '22 11:09

SpaceTrucker