Search code examples
unit-testingapache-camelapache-camel-3

Unit testing camel routes containing serviceCall()


I have a camel route that reaches out to a URL and does some processing with the results:

from("direct:doURL")
    .routeId("urlRouteId")
    .to("http://host:port/path")
    .process(e -> {
        //Do Stuff
    });

I can run unit test on that route without making an actual call to the URL by intercepting the call in my unit test like follows:

AdviceWith.adviceWith(context, "urlRouteId", a ->
    a.interceptSendToEndpoint("http://host:port/path").skipSendToOriginalEndpoint().to("mock:test")
);

I’m updating that route to use .serviceCall() instead to look up the actual URL of the service, something like this:

from("direct:doService")                
    .routeId("servcieRouteId")
    .serviceCall("myService/path")
    .process(e -> {
        //Do Stuff
    });

This works great, but I don’t know how to do a similar unit test on this route. Is there some sort of LoadBalancerClient I can use for testing? What is the standard way to unit test routes with service calls? I've been googling around for awhile and haven't had much luck, any ideas?

Thanks


Solution

  • You can give serviceCall endpoint an id and then use weaveById.

    from("direct:doURL")
        .routeId("urlRouteId")
        .serviceCall("foo").id("serviceCall")
        .log(LoggingLevel.INFO, "body ${body}");
    
    AdviceWith.adviceWith(context(), "urlRouteId", a -> {
    
        a.weaveById("serviceCall")
            .replace()
            .setHeader(Exchange.HTTP_RESPONSE_CODE).constant(200)
            .setBody().simple("Hello from service");
    });
    

    Alternatively if service is a bean in camel registry then you could probably override bindToRegistry method and use Mockito to create a mock service.

    Also instead of using interceptSendToEndpoint it would likely be much simpler to just use weaveByToUri("http*").replace() instead.

    Example generic method for replacing http-endpoints

    private void replaceHttpEndpointWithSimpleResponse(String routeId, String simpleResponse) throws Exception {
    
            AdviceWith.adviceWith(context(), routeId, a -> {
                a.weaveByToUri("http*")
                    .replace()
                    .setHeader(Exchange.HTTP_RESPONSE_CODE).constant(200)
                    .setBody().simple(simpleResponse);
            });
    }