In Apache Camel, how can unit tests introduce false endpoints instead of real ones?

I am implementing a message translation template with Apache Camel to consume messages from a RESTful endpoint and send them to the AMQP endpoint.

The embedded application is based on Spring Boot, and therefore I use the Camel spring-boot component to integrate the two frameworks. As suggested in the documentation for this link spring-boot, I implement my Camel route inside the @Configuration -annotated class, which extends RouteBuilder :

 @Component public class MyRestToAmqpRouter extends RouteBuilder { @Override public void configure() throws Exception { from("jetty:http://my-restful-url") .process(exchange -> { // convert the message body from JSON to XML, take some // incoming header values and put them in the outgoing // body, etc... }).to("rabbitmq://my-rabbitmq-url"); } } 

My question is about how to switch to unit testing this translation without requiring an actual RESTful endpoint or a configured RabbitMQ broker? I read a lot of online examples, as well as the camel in action book ... and it seems like a typical Camel unit testing approach is to cut-paste the route into your unit test and replace one or more endpoint URLs with " mock:whatever ".

I think sorta works ... but it is terribly fragile and your test suite will not know when someone later changes the real code without updating the unit test.

I tried to adapt some examples of testing modules on spring using mocks, for example:

 @RunWith(CamelSpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {Application.class}) public class MyRestToAmqpRouterTest extends AbstractJUnit4SpringContextTests { @Produce(uri = "jetty:http://my-restful-url") private ProducerTemplate fakeRest; @EndpointInject(uri = "rabbitmq://my-rabbit-url") private MockEndpoint fakeRabbit; @Test @DirtiesContext public void testRouter() throws InterruptedException { fakeRabbit.expectedMessageCount(1); fakeRest.sendBodyAndHeader("", "header-1", "some value"); fakeRabbit.assertIsSatisfied(); } } 

My hope was that Camel would use these final URLs from unit test, register them as mocks ... and then use layouts, not the real endpoint, when real code tries to use these URLs.

However, I am not sure if this is possible. When I use real URLs in the unit test, I get an IllegalArgumentException because you apparently can't inject the β€œreal” endpoint URL into the MockEndpoint instance (only URLs with the prefix β€œ mock: ”).

When I use the endpoint URL " mock:... " in my unit test, then it is useless because there is no binding to the real endpoint URL in the tested class. Thus, the real endpoint URL will never be redefined. When real code is executed, it simply uses the real endpoint as usual (and the goal is to be able to test without an external dependency on RabbitMQ).

Am I missing something on a truly fundamental level here? It seems that for unit tests, one could introduce fake routes in such a class so that the code under test can switch from real endpoints to layouts without even realizing it. Alternatively, I believe that I could reorganize my code so that the anonymous Processor upgraded to a standalone class ... and then I could unit test its translation logic regardless of the route. But it just looks like an incomplete test.

+7
java spring spring-boot apache-camel eai
source share
1 answer

Some pointers to what you can do.

You can read the camel book about testing again and pay attention to tips with

And there is also mockEndpointsAndSkip

And you can also use the stub component

Or use property placeholders on your routes, and then configure uris for layout / stub, etc. for testing and use real for production

+3
source share

All Articles