spring-bootapache-camelcamel-test

Spring Boot Apache Camel Routes testing


I have a Springboot application, where I have some Camel routes configured.

public class CamelConfig {
    private static final Logger LOG = LoggerFactory.getLogger(CamelConfig.class);

    @Value("${activemq.broker.url:tcp://localhost:61616}")
    String brokerUrl;

    @Value("${activemq.broker.maxconnections:1}")
    int maxConnections;

    @Bean
    ConnectionFactory jmsConnectionFactory() {
        PooledConnectionFactory pooledConnectionFactory = new PooledConnectionFactory(new ActiveMQConnectionFactory(brokerUrl));
        pooledConnectionFactory.setMaxConnections(maxConnections);
        return pooledConnectionFactory;
    }

    @Bean
    public RoutesBuilder route() {
        LOG.info("Initializing camel routes......................");
        return new SpringRouteBuilder() {
            @Override
            public void configure() throws Exception {
                from("activemq:testQueue")
                  .to("bean:queueEventHandler?method=handleQueueEvent");
            }
        };
    }
}

I want to test this route from activemq:testQueue to queueEventHandler::handleQueueEvent. I tried different things mentioned here http://camel.apache.org/camel-test.html, but doesn't seem to get it working.

I am trying to do something like this:

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = {CamelConfig.class,   CamelTestContextBootstrapper.class})
    public class CamelRouteConfigTest {

    @Produce(uri = "activemq:testQueue")
    protected ProducerTemplate template;

    @Test
    public void testSendMatchingMessage() throws Exception {
        template.sendBodyAndHeader("testJson", "foo", "bar");
        // Verify handleQueueEvent(...) method is called on bean queueEventHandler by mocking
    }

But my ProducerTemplate is always null. I tried auto-wiring CamelContext, for which I get an exception saying it cannot resolve camelContext. But that can be resolved by adding SpringCamelContext.class to @SpringBootTest classes. But my ProducerTemplate is still null.

Please suggest. I am using Camel 2.18 and Spring Boot 1.4.


Solution

  • This is how I did this finally:

        @RunWith(SpringRunner.class)
        public class CamelRouteConfigTest extends CamelTestSupport {
        
            private static final Logger LOG = LoggerFactory.getLogger(CamelRouteConfigTest.class);
            private static BrokerService brokerSvc = new BrokerService();
        
            @Mock
            private QueueEventHandler queueEventHandler;
        
            @BeforeClass
            // Sets up an embedded broker
            public static void setUpBroker() throws Exception {
                brokerSvc.setBrokerName("TestBroker");
                brokerSvc.addConnector("tcp://localhost:61616");
                brokerSvc.setPersistent(false);
                brokerSvc.setUseJmx(false);
                brokerSvc.start();
            }
        
            @Override
            protected RoutesBuilder createRouteBuilder() throws Exception {
                return new CamelConfig().route();
            }
        
            // properties in .yml has to be loaded manually. Not sure of .properties file
            @Override
            protected Properties useOverridePropertiesWithPropertiesComponent() {
                YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
                try {
                    PropertySource<?> applicationYamlPropertySource = loader.load(
                        "properties", new ClassPathResource("application.yml"),null);// null indicated common properties for all profiles.
                    Map source = ((MapPropertySource) applicationYamlPropertySource).getSource();
                    Properties properties = new Properties();
                    properties.putAll(source);
                    return properties;
                } catch (IOException e) {
                    LOG.error("application.yml file cannot be found.");
                }
        
                return null;
            }
        
            @Override
            protected JndiRegistry createRegistry() throws Exception {
                JndiRegistry jndi = super.createRegistry();
                MockitoAnnotations.initMocks(this);
                jndi.bind("queueEventHandler", queueEventHandler);
        
                return jndi;
            }
        
            @Test
            // Sleeping for a few seconds is necessary, because this line template.sendBody runs in a different thread and
            // CamelTest takes a few seconds to do the routing.
            public void testRoute() throws InterruptedException {
                template.sendBody("activemq:productpushevent", "HelloWorld!");
                Thread.sleep(2000);
                verify(queueEventHandler, times(1)).handleQueueEvent(any());
            }
        
            @AfterClass
            public static void shutDownBroker() throws Exception {
                brokerSvc.stop();
            }
        }