0

Available examples of the usage of the Camel Test component show how to test the expectations of a route:

However what I need to do is mock the body (manually setting it) of an intermediate route, e.g.:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">

    <bean id="exampleBean" class="xxx.ExampleBean"/>

    <routeContext id="routesTest" xmlns="http://camel.apache.org/schema/spring">

        <route>
            <from uri="direct:route1" />
            <to uri="direct:route2" />
            <log message="${body}"/>
        </route>

        <route>
            <from uri="direct:route2"/>
            <to uri="bean:exampleBean"/>
            <to uri="direct:route3" />
        </route>

        <route>
            <from uri="direct:route3"/>
            <log message="${body}"/>
        </route>

    </routeContext>

</beans>

In this scenario I want to completely avoid the actual execution of bean:exampleBean, mocking the result of its execution.

My test class:

public class MyTests extends CamelSpringTestSupport {

    @Produce(uri = "direct:route1")
    protected ProducerTemplate inputProducerTemplate;

    @EndpointInject(uri = "mock:bean:exampleBean")
    protected MockEndpoint mockBeanExampleBean;

    @Test
    public void testRoute() throws Exception {

        CompletableFuture<Object> future = inputProducerTemplate.asyncSendBody("direct:route1", "Some message");
        Object o = future.get();
       
    }

    @Override
    public String isMockEndpoints() {
        return "bean:exampleBean";
    }

    @Override
    protected AbstractApplicationContext createApplicationContext() {
        return new ClassPathXmlApplicationContext("spring/gesti-test-application-context.xml");
    }

}

public class ExampleBean {

    public String enhance(String message) {
        System.out.println(message);
        //Here I would call a REST API
        return "MY API RESULT";
    }

}

When using mockBeanExampleBean.whenAnyExchangeReceived(exchange -> exchange.getMessage().setBody("My message")); it allows to override the input to exampleBean, but doesn't avoid its execution.

codependent
  • 23,193
  • 31
  • 166
  • 308

2 Answers2

0

In the context of your unit test, route2 might be a "mock" component instead. A clean way of achieving that is to declare the route(s) in the properties file. The legibility of the routes gets harder, though.

Then, you could:

@EndpointInject("mock://route2")
MockEndpoint mockSecondStep;

mockSecondStep.whenExchangeReceived(1, e -> {
List whatever = new ArrayList<>();
e.getMessage().setBody(whatever);
});
  • Your solution still doesn't work in my scenario, I want to avoid the execution of the mocked processor (exampleBean) – codependent Aug 06 '21 at 08:54
0

I solved it using an InterceptStrategy:

public class MyTests extends CamelSpringTestSupport {

    @Test
    public void testRoute() throws Exception {

        CompletableFuture<Object> future = template.asyncSendBody("direct:route1", "Some message");
        Object o = future.get();
        assertEquals("INTERCEPTED!", o);
    }

    @Override
    protected AbstractApplicationContext createApplicationContext() {
        return new ClassPathXmlApplicationContext("spring/gesti-test-application-context.xml");
    }

        @Override
    protected RouteBuilder createRouteBuilder() {
        return new RouteBuilder() {
            @Override
            public void configure() {
                context.getProcessorDefinition("bean:exampleBean").addInterceptStrategy(
                        (context, definition, target, nextTarget) -> exchange -> exchange.getOut().setBody("INTERCEPTED!"));
            }
        };
    }

}

public class ExampleBean {

    public String enhance(String message) {
        System.out.println(message);
        //Here I would call a REST API
        return "MY API RESULT";
    }

}

codependent
  • 23,193
  • 31
  • 166
  • 308