...
Code Block | ||
---|---|---|
| ||
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-test-cdi</artifactId> <scope>test</test>scope> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency> |
...
Camel CDI test provides the @Order
annotation that you can use to execute the test methods in a particular sequence, e.g.:
Code Block | ||
---|---|---|
| ||
@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 @Dependent
CDI scope), or one test class instance for the entire test class execution using the @ApplicationScoped
scope, e.g.:
Code Block | ||
---|---|---|
| ||
@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 @Beans
annotation provided by Camel CDI test. For example, if you need to add a route to your Camel context, instead of declaring a RouteBuilder
bean with a nested class, you can declare a managed bean, e.g.:
...
You can see the tests in the camel-example-cdi-test
example for a thorough overview of the following testing patterns for Camel CDI applications.
Info |
---|
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 routes
You may want to add some Camel routes to your Camel CDI applications for testing purpose. For example to route some exchanges to a MockEndpoint
instance. You can do that by declaring a RouteBuilder
bean within the test class as you would normally do in your application code, e.g.:
...
You can find more information in auto-detecting Camel routes.
Bean alternatives
You 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 applicationIn case you prefer declaring the RouteBuilder
bean in a separate class, for example to share it more easily across multiple test classes, you can use the @Beans
annotation to instruct Camel CDI test to deploy that class as a CDI bean, e.g.:
Code Block | ||
---|---|---|
| ||
@RunWith(CamelCdiRunner.class) @Beans(classes = TestRoute.class) public class ApplicationCamelCdiTest { // ... } |
Bean alternatives
You 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:
Code Block | ||
---|---|---|
| ||
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:
Code Block | ||
---|---|---|
| ||
@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
, e.g.:
Code Block | ||
---|---|---|
| ||
@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 CamelCdiRunner
JUnit runner, you can do that with the @Beans
annotation provided by the Camel CDI test module, e.g.:
Code Block | ||
---|---|---|
| ||
@RunWith(CamelCdiRunner.class) @Beans(alternatives = AlternativeBean.class) public class CamelCdiTest { @Test public void testAlternativeBean(@Uri("direct:in") ProducerTemplate producer @ContextName("camel-test-cdi") static class Hello extends RouteBuilder { @Override public void configure() { from@Uri("directmock:inout").bean("bean").to("direct:out"); MockEndpoint mock) throws InterruptedException { mock.expectedMessageCount(1); mock.expectedBodiesReceived("test with } alternative bean!"); } } |
And the corresponding bean:
Code Block | ||
---|---|---|
| ||
@Named("bean") public class Bean { public String process(@Body String body) {producer.sendBody("test"); MockEndpoint.assertIsSatisfied(1L, TimeUnit.SECONDS, mock); } static class TestRoute extends returnRouteBuilder body;{ } } |
Then you can replace the bean above in your tests by declaring an alternative bean, annotated with @Alternative
, e.g.:
Code Block | ||
---|---|---|
| ||
@Alternative @Named("bean") public class AlternativeBean {@Override public String process(@Bodypublic Stringvoid bodyconfigure() { return body + " with alternative bean!"; from("direct:out").routeId("test").to("mock:out"); } } } |
And you need to activate (a.k.a. select in CDI terminology) this alternative bean in your tests. If your using the CamelCdiRunner
JUnit runner, you can do that with the @Beans
annotation provided by the Camel CDI test moduleIf you're using Arquillian as testing framework, you need to activate the alternative in your deployment method, e.g.:
Code Block | ||
---|---|---|
| ||
@RunWith(CamelCdiRunner.class) @Beans(alternatives = AlternativeBean.class) public class CamelCdiTest { @Test@RunWith(Arquillian.class) public class CamelCdiTest { @Deployment public static Archive deployment() { return ShrinkWrap.create(JavaArchive.class) // Camel CDI .addPackage(CdiCamelExtension.class.getPackage()) // Test classes public void testAlternativeBean(@Uri("direct:in") ProducerTemplate producer.addPackage(Application.class.getPackage()) // Bean archive deployment descriptor .addAsManifestResource( new StringAsset( @Uri("mock:out") MockEndpoint mock) throws InterruptedException { mockDescriptors.expectedMessageCountcreate(1BeansDescriptor.class); mock.expectedBodiesReceived("test with alternative bean!"); producer.sendBodygetOrCreateAlternatives("test"); MockEndpoint.assertIsSatisfied(1L, TimeUnit.SECONDS, mock); } static class TestRoute extends RouteBuilder { .stereotype(MockAlternative.class.getName()).up() @Override public void configure.exportAsString() { ), from("direct:out").routeId("test").to("mock:out""beans.xml"); } }//... } |
Camel context
...
customization
You may need to customise 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.:
...