Since we're on a major migration process of this website, some component documents here are out of sync right now. In the meantime you may want to look at the early version of the new website
https://camel.apache.org/staging/
We would very much like to receive any feedback on the new site, please join the discussion on the Camel user mailing list.
CDI TestingTesting is a crucial part of any development or integration work. In case you're using the Camel CDI integration for your applications, you have a number of options to ease testing. You can use CDI for IoC and the Camel testing endpoints like There are a number of supported approaches for testing with CDI in Camel:
Camel CDI TestWith this approach, your test classes use the JUnit runner provided in Camel CDI test. This runner manages the lifecycle of a standalone CDI container and automatically assemble and deploy the System Under Test (SUT) based on the classpath into the container. It deploys the test class as a CDI bean so that dependency injection and any CDI features is available within the test class. Maven users will need to add the following dependency to their <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-test-cdi</artifactId> <scope>test</scope> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency> Here is a simple unit test using the @RunWith(CamelCdiRunner.class) public class CamelCdiTest { @Inject CamelContext context; @Test public void test() { assertThat("Camel context status is incorrect!", context.getStatus(), is(equalTo(ServiceStatus.Started))); } } CDI injection is also available for test method parameters, e.g.: @RunWith(CamelCdiRunner.class) public class CamelCdiTest { @Test public void test(@Uri("direct:foo") ProducerTemplate producer) { producer.sendBody("bar"); } } Camel CDI test provides the @RunWith(CamelCdiRunner.class) public class CamelCdiTest { @Test @Order(1) public void firstTestMethod() { } @Test @Order(2) public void secondTestMethod() { } } One CDI container is bootstrapped for the entire execution of the test class. Besides, the test class is deployed as a CDI bean, so that you can control how the runner instantiate the test class, either one test class instance for each test method (the default, depending on the built-in default @ApplicationScoped @RunWith(CamelCdiRunner.class) public class CamelCdiTest { int counter; @Test @Order(1) public void firstTestMethod() { counter++; } @Test @Order(2) public void secondTestMethod() { assertEquals(counter, 1); } } In case you need to add additional test beans, you can use the class TestRoute extends RouteBuilder { @Override public void configure() { from("direct:foo").to("mock:bar"); } } And add it with the @RunWith(CamelCdiRunner.class) @Beans(classes = TestRoute.class) public class CamelCdiTest { } ArquillianWith this approach, you use the JUnit runner or TestNG support provided by Arquillian to delegate the bootstrap of the CDI container. You need to declare a @RunWith(Arquillian.class) public class CamelCdiJavaSeTest { @Deployment public static Archive deployment() { return ShrinkWrap.create(JavaArchive.class) // Camel CDI .addPackage(CdiCamelExtension.class.getPackage()) // Test classes .addPackage(Application.class.getPackage()) // Bean archive deployment descriptor .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); } @Inject CamelContext context; @Test public void test() { assertThat("Camel context status is incorrect!", context.getStatus(), is(equalTo(ServiceStatus.Started))); } } In that example, you can use any Java SE Arquillian embedded container adapter, like the Weld embedded container adapter e.g. with Maven you need that complete set of dependencies: <dependencies> <dependency> <groupId>org.jboss.arquillian.junit</groupId> <artifactId>arquillian-junit-container</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.jboss.shrinkwrap.descriptors</groupId> <artifactId>shrinkwrap-descriptors-depchain</artifactId> <type>pom</type> <scope>test</scope> </dependency> <dependency> <groupId>org.jboss.arquillian.container</groupId> <artifactId>arquillian-weld-se-embedded-1.1</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.jboss.weld</groupId> <artifactId>weld-core</artifactId> <scope>test</scope> </dependency> </dependencies> Using ShrinkWarp Descriptors, you have a complete control over the configuration and kind of Camel CDI applications you want to test. For example, to test a Camel CDI application that uses the Camel REST DSL configured with the Servlet component, you need to create a Web archive, e.g.: @RunWith(Arquillian.class) public class CamelCdiWebTest { @Deployment public static Archive<?> createTestArchive() { return ShrinkWrap.create(WebArchive.class) .addClass(Application.class) .addAsWebInfResource(EmptyAsset.INSTANCE, ArchivePaths.create("beans.xml")) .setWebXML(Paths.get("src/main/webapp/WEB-INF/web.xml").toFile()); } @Test @RunAsClient public void test(@ArquillianResource URL url) throws Exception { assertThat(IOHelper.loadText(new URL(url, "camel/rest/hello").openStream()), is(equalTo("Hello World!\n"))); } } In the example above, you can use any Arquillian Web container adapter, like the Jetty embedded container adapter e.g. with Maven you need the complete following set of dependencies: </dependencies> <dependency> <groupId>org.jboss.arquillian.junit</groupId> <artifactId>arquillian-junit-container</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.jboss.arquillian.testenricher</groupId> <artifactId>arquillian-testenricher-resource</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.jboss.shrinkwrap.descriptors</groupId> <artifactId>shrinkwrap-descriptors-depchain</artifactId> <type>pom</type> <scope>test</scope> </dependency> <dependency> <groupId>org.jboss.weld.servlet</groupId> <artifactId>weld-servlet</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-webapp</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-annotations</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.jboss.arquillian.container</groupId> <artifactId>arquillian-jetty-embedded-9</artifactId> <scope>test</scope> </dependency> </dependencies> You can see the tests in the PAX ExamIf you target OSGi as runtime environment for your Camel CDI applications, you can use PAX Exam to automate the deployment of your tests into an OSGi container, for example into Karaf, e.g.: @RunWith(PaxExam.class) @ExamReactorStrategy(PerClass.class) public class PaxCdiOsgiTest { @Configuration public Option[] config() throws IOException { return options( // Karaf configuration karafDistributionConfiguration() .frameworkUrl( maven() .groupId("org.apache.karaf") .artifactId("apache-karaf") .versionAsInProject() .type("zip")) .name("Apache Karaf") .unpackDirectory(new File("target/paxexam/unpack/")), // PAX CDI Weld features( maven() .groupId("org.ops4j.pax.cdi") .artifactId("pax-cdi-features") .type("xml") .classifier("features") .versionAsInProject(), "pax-cdi-weld"), // Karaf Camel commands mavenBundle() .groupId("your.application.groupId") .artifactId("your.application.artifactId") .versionAsInProject() ); } @Inject private CamelContext context; @Test public void testContextStatus() { assertThat("Camel context status is incorrect!", context.getStatus(), equalTo(ServiceStatus.Started)); } } You can see the tests in the Testing PatternsYou can see the tests in the While the patterns above are illustrated using the Camel CDI test module, they should equally work with Arquillian and PAX Exam unless otherwise stated or illustrated with a specific example. Test routesYou may want to add some Camel routes to your Camel CDI applications for testing purpose. For example to route some exchanges to a @RunWith(CamelCdiRunner.class) public class CamelCdiTest { // Declare a RouteBuilder bean for testing purpose // that is automatically added to the Camel context static class TestRoute extends RouteBuilder { @Override public void configure() { from("direct:out").routeId("test").to("mock:out"); } // And retrieve the MockEndpoint for further assertions @Inject @Uri("mock:out") MockEndpoint mock; } You can find more information in auto-detecting Camel routes. In case you prefer declaring the @RunWith(CamelCdiRunner.class) @Beans(classes = TestRoute.class) public class CamelCdiTest { // ... } Bean alternativesYou may want to replace a bean that is used in your Camel routes by another bean for testing purpose, for example to mock it or change the behaviour of the application bean. Imagine you have the following route in your application: public class Application { @ContextName("camel-test-cdi") static class Hello extends RouteBuilder { @Override public void configure() { from("direct:in").bean("bean").to("direct:out"); } } } And the corresponding bean: @Named("bean") public class Bean { public String process(@Body String body) { return body; } } Then you can replace the bean above in your tests by declaring an alternative bean, annotated with @Alternative @Named("bean") public class AlternativeBean { public String process(@Body String body) { return body + " with alternative bean!"; } } And you need to activate (a.k.a. select in CDI terminology) this alternative bean in your tests. If your using the @RunWith(CamelCdiRunner.class) @Beans(alternatives = AlternativeBean.class) public class CamelCdiTest { @Test public void testAlternativeBean(@Uri("direct:in") ProducerTemplate producer @Uri("mock:out") MockEndpoint mock) throws InterruptedException { mock.expectedMessageCount(1); mock.expectedBodiesReceived("test with alternative bean!"); producer.sendBody("test"); MockEndpoint.assertIsSatisfied(1L, TimeUnit.SECONDS, mock); } static class TestRoute extends RouteBuilder { @Override public void configure() { from("direct:out").routeId("test").to("mock:out"); } } } If you're using Arquillian as testing framework, you need to activate the alternative in your deployment method, e.g.: @RunWith(Arquillian.class) public class CamelCdiTest { @Deployment public static Archive deployment() { return ShrinkWrap.create(JavaArchive.class) // Camel CDI .addPackage(CdiCamelExtension.class.getPackage()) // Test classes .addPackage(Application.class.getPackage()) // Bean archive deployment descriptor .addAsManifestResource( new StringAsset( Descriptors.create(BeansDescriptor.class) .getOrCreateAlternatives() .stereotype(MockAlternative.class.getName()).up() .exportAsString()), "beans.xml"); } //... } Camel context customizationYou may need to customize your Camel contexts for testing purpose, for example disabling JMX management to avoid TCP port allocation conflict. You can do that by declaring a custom Camel context bean in your test class, e.g.: @RunWith(CamelCdiRunner.class) public class CamelCdiTest { @Default @ContextName("camel-test-cdi") @ApplicationScoped static class CustomCamelContext extends DefaultCamelContext { @PostConstruct void customize() { disableJMX(); } } } In that example, the custom Camel context bean declared in the test class will be used during the test execution instead of the default Camel context bean provided by the Camel CDI component. Routes advising with |