Kaigo
Kaigo

Reputation: 1599

Unit testing Camel/RabbitMQ routes issue

I'm having issue unit testing a camel route which uses rabbitmq for the broker.

I've been researching for weeks but haven't found an effective way to do this.

Firstly, I was having an issue with NOT calling rabbitmq in my test, and to keep this a unit test and not an integration test. This was achieved by using advicewith and switch out the queue for mock queues.

However, with the following code the messages are not reaching the result or end queue (MOBILE_QUEUE).

java.lang.AssertionError: mock://result Received message count. Expected: <1> but was: <0> Expected :<1> Actual :<0>


Here is my route, which imports rabbitmq.class

from(TEST_QUEUE).to(MOBILE_QUEUE).routeId("test2phone");

My config rabbitmq.class

@Component
public class RabbitMQ extends Properties {

    public final String TEST_QUEUE = CreateRabbitMQQueue("TestQueue", "camel");
    public final String MOBILE_QUEUE = CreateRabbitMQQueue("MobileQueue", "camel");

    public static String CreateRabbitMQQueue(String QueueName, String RoutingKey)
    {
        String hostv;
        String portv;
        String username;
        String password;

        hostv = "mq-staging";
        portv = System.getenv("SERVICE_PORT_AMQP");
        username = System.getenv("V_RABBIT_USERNAME");
        password = System.getenv("V_RABBIT_PASSWORD");

        UriComponentsBuilder uriBuilder = UriComponentsBuilder
                .fromPath("/" )
                .scheme("rabbitmq")
                .host(hostv)
                .port(portv)
                .path("/" + QueueName)
                .queryParam("username",username)
                .queryParam("password", password)
                .queryParam("routingKey",RoutingKey)
                .queryParam("queue","Q" + QueueName);

        return uriBuilder.toUriString();
    }

}

And my unit test

@RunWith(CamelSpringRunner.class)
@MockEndpoints
@UseAdviceWith
@SpringBootTest
public class RouteTester extends CamelTestSupport {

    String TEST_QUEUE;
    String MOBILE_QUEUE;

    @Autowired
    Routes routes;

    @Autowired
    CamelContext context;

    @Autowired
    ProducerTemplate template;

    @Before
    public void setUp() throws Exception {
        TEST_QUEUE = routes.getTEST_QUEUE();
        MOBILE_QUEUE = routes.getMOBILE_QUEUE();
        context.getRouteDefinition("test2phone").adviceWith(context, new Routes() {
            @Override
            public void configure() throws Exception {
                interceptSendToEndpoint(TEST_QUEUE)
                        .skipSendToOriginalEndpoint()
                        .to("mock:testQ");
                interceptSendToEndpoint(MOBILE_QUEUE)
                        .skipSendToOriginalEndpoint()
                        .to("mock:result");
            }
        });
        context.start();
    }

    @Test
    public void testTest() throws Exception {
        String body = "hello123";

        MockEndpoint resultEndpoint = context.getEndpoint("mock:result", MockEndpoint.class);

        resultEndpoint.expectedMessageCount(1);
        resultEndpoint.expectedBodiesReceived(body);
        template.sendBody(TEST_QUEUE, body);
        resultEndpoint.assertIsSatisfied();
    }

    @After
    public void TearDown() throws Exception {
        context.stop();
    }

}

Upvotes: 0

Views: 1543

Answers (1)

Bedla
Bedla

Reputation: 4919

interceptSendToEndpoint is useful to intercepting output endpoint. You probably want replace input endpoint and intercept output endpoint. See AdviceWith.

This should work:

context.getRouteDefinition("test2phone").adviceWith(context, new AdviceWithRouteBuilder() {
    @Override
    public void configure() throws Exception {
        replaceFromWith("direct:test");
        interceptSendToEndpoint(MOBILE_QUEUE)
            .skipSendToOriginalEndpoint()
            .to("mock:result");
        }
});

And test your route with:

template.sendBody("direct:test", body);

Upvotes: 1

Related Questions