...
Name | Testing Frameworks Supported | Description | Required Camel Test Dependencies |
---|---|---|---|
|
| Provided by:
These . These base classes provide feature parity with the simple simple |
|
Plain Spring Test |
| Extend Either extend the abstract base classes (:
provided ) provided in Spring Test or use the Spring Test JUnit4 runner. These These approaches support both the Camel annotations and Spring annotations. However, but they do not NOT have feature parity with org with:
|
|
Camel Enhanced Spring Test |
| Either: Use the
| JUnit 3.x (deprecated) - JUnit 4.x - TestNG - |
CamelSpringTestSupport
The following Spring test support classes:
org.apache.camel.test.CamelSpringTestSupport
...
org.apache.camel.test.junit4.CamelSpringTestSupport
, andorg.apache.camel.testng.CamelSpringTestSupport
extend CamelSpringTestSupport extend their non-Spring aware counterparts (:
org.apache.camel.test.CamelTestSupport
...
org.apache.camel.test.junit4.CamelTestSupport
,
...
- and
org.apache.camel.testng.CamelTestSupport
) and deliver integration with Spring into your test classes.
Instead of instantiating the Instead of instantiating the CamelContext
and routes programmatically, these classes rely on a Spring context to wire the needed components together. If your test extends one of these classes, you must provide the Spring context by implementing the following method.
Code Block | ||
---|---|---|
| ||
protected abstract AbstractApplicationContext createApplicationContext(); |
...
In this approach, your test classes directly inherit from the Spring Test abstract test classes or use the JUnit 4.x test runner provided in Spring Test. This approach supports dependency injection into your test class and the full suite of Spring Test annotations but does not support the features provided by the the CamelSpringTestSupport
classes.
Plain Spring Test using JUnit 3.x with XML Config Example
Here is a simple unit test using JUnit 3.x support from Spring Test using XML Config.
Wiki Markup |
---|
{snippet:lang=java|id=example|url=camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/patterns/FilterTest.java} |
@DirtiesContext
on on the test methods to force Spring Testing to automatically reload the CamelContext after each test method - this ensures that the tests don't clash with each other (e.g. one test method sending to an endpoint that is then reused in another test method).Also notice the use of @ContextConfiguration
to to indicate that by default we should look for the FilterTest-context.xml on the classpath to configure the test case which looks like this
Wiki Markup |
---|
{snippet:lang=xml|id=example|url=camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/patterns/FilterTest-context.xml} |
calledFilterTest-context.
xml from xml
from the classpath in the same package structure as the the FilterTest
class and initialize it along with any Camel routes we define inside it, then inject inject theCamelContextinstance
into our test case.For instance, like this maven folder layout:
Code Block |
---|
src/test/java/org/apache/camel/spring/patterns/FilterTest.java src/test/resources/org/apache/camel/spring/patterns/FilterTest-context.xml |
Plain Spring Test
...
Using JUnit 4.x
...
With Java Config Example
You can completely avoid using an XML configuration file by using Spring Java Config. Here is a unit test using JUnit 4.x support from Spring Test using Java Config.
Wiki Markup |
---|
{snippet:lang=java|id=example|url=camel/trunk/components/camel-spring-javaconfig/src/test/java/org/apache/camel/spring/javaconfig/patterns/FilterTest.java} |
ContextConfig
class does all of the configuration; so your entire test case is contained in a single Java class. We currently have to reference by class name this class in the @ContextConfiguration
which is a bit ugly. Please vote for SJC-238 to address this and make Spring Test work more cleanly with Spring JavaConfig.Plain Spring Test
...
Using JUnit 4.0.x Runner
...
With XML Config
You can avoid extending Spring classes by using the the SpringJUnit4ClassRunner
provided by Spring Test. This custom JUnit runner means you are free to choose your own class hierarchy while retaining all the capabilities of Spring Test.
Info |
---|
This is for Spring 4.0.x. If you use Spring 4.1 or newer, then see the next section. |
Code Block | ||
---|---|---|
| ||
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration public class MyCamelTest { @Autowired protected CamelContext camelContext; @EndpointInject(uri = "mock:foo") protected MockEndpoint foo; @Test @DirtiesContext public void testMocksAreValid() throws Exception { // ... foo.message(0).header("bar").isEqualTo("ABC"); MockEndpoint.assertIsSatisfied(camelContext); } } |
Plain Spring Test
...
Using JUnit 4.1.x Runner
...
With XML Config
You can avoid extending Spring classes by using the the SpringJUnit4ClassRunner
provided by Spring Test. This custom JUnit runner means you are free to choose your own class hierarchy while retaining all the capabilities of Spring Test.
Info |
---|
When using From Spring 4.1 onwards, you need to use the the |
Code Block | ||
---|---|---|
| ||
@RunWith(CamelSpringJUnit4ClassRunner.class) @BootstrapWith(CamelTestContextBootstrapper.class) @ContextConfiguration public class MyCamelTest { @Autowired protected CamelContext camelContext; @EndpointInject(uri = "mock:foo") protected MockEndpoint foo; @Test @DirtiesContext public void testMocksAreValid() throws Exception { // ... foo.message(0).header("bar").isEqualTo("ABC"); MockEndpoint.assertIsSatisfied(camelContext); } } |
Camel Enhanced Spring Test
Using the org.apache.camel.test.junit4.
CamelSpringJUnit4ClassRunner runner CamelSpringJUnit4ClassRunner
runner with the @RunWith
annotation annotation or extending extending org.apache.camel.testng.AbstractCamelTestNGSpringContextTests
provides the full feature set of Spring Test with support for the feature set provided in the the CamelTestSupport
classes.
A A number of Camel specific annotations have been developed in order to provide for declarative manipulation of the Camel context(s) involved in the test. These annotations free your test classes from having to inherit from the the CamelSpringTestSupport
classes and also reduce the amount of code required to customize the tests.
Annotation Class | Applies To | Description | Default Behavioir If Not Present | Default Behavior If Present |
---|---|---|---|---|
|
| Indicates if JMX should be globally disabled in the CamelContexts that are bootstrapped during the test through the use of Spring Test loaded application contexts. | JMX is disabled | JMX is disabled |
|
| Indicates if certain route builder classes should be excluded from discovery. Initializes a a | Not enabled and no routes are excluded | No routes are excluded |
|
| Indicates if the CamelContexts that are bootstrapped during the test through the use of Spring Test loaded application contexts should use lazy loading of type converters. | Type converters are not lazy loaded | Type converters are not lazy loaded |
|
| Triggers the auto-mocking of endpoints whose URIs match the provided filter. The default filter is is | Not enabled | All endpoints are sniffed and recorded in a mock endpoint. |
|
| Triggers the auto-mocking of endpoints whose URIs match the provided filter. The default filter is | Not enabled | All endpoints are sniffed and recorded in a mock endpoint. The original endpoint is not invoked. |
|
| Indicates that the annotated method returns an organ | N/A | The returned returned |
|
| Indicates to set the shutdown timeout of all CamelContexts instantiated through the use of Spring Test loaded application contexts. If no annotation is used, the timeout is automatically reduced to 10 seconds by the test framework. | 10 seconds | 10 seconds |
|
| Indicates the use of of The test author is responsible for injecting the Camel contexts into the test and executing executing | CamelContexts do not automatically start. | CamelContexts do not automatically start. |
org.apache.camel.test.spring.UseOverridePropertiesWithPropertiesComponent | Method | Camel 2.16:Indicates that the annotated method returns a a java.util.Properties for use in the test, and that those properties override any existing properties configured on the PropertiesComponent . | Override properties |
The following example illustrates the use of the @MockEndpoints
annotation annotation in order to setup mock endpoints as interceptors on all endpoints using the Camel Log component and the @DisableJmx
annotation to enable JMX which is disabled during tests by default. Note that
Info |
---|
Note: we still use the @DirtiesContext annotation to ensure that the CamelContext, routes, and mock endpoints are reinitialized between test methods. |
Code Block | ||
---|---|---|
| ||
@RunWith(CamelSpringJUnit4ClassRunner.class) @BootstrapWith(CamelTestContextBootstrapper.class) @ContextConfiguration @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) @MockEndpoints("log:*") @DisableJmx(false) public class CamelSpringJUnit4ClassRunnerPlainTest { @Autowired protected CamelContext camelContext2; protected MockEndpoint mockB; @EndpointInject(uri = "mock:c", context = "camelContext2") protected MockEndpoint mockC; @Produce(uri = "direct:start2", context = "camelContext2") protected ProducerTemplate start2; @EndpointInject(uri = "mock:log:org.apache.camel.test.junit4.spring", context = "camelContext2") protected MockEndpoint mockLog; @Test public void testPositive() throws Exception { mockC.expectedBodiesReceived("David"); mockLog.expectedBodiesReceived("Hello David"); start2.sendBody("David"); MockEndpoint.assertIsSatisfied(camelContext); } |
Adding
...
More Mock
...
Expectations
If you wish to programmatically add any new assertions to your test you can easily do so with the following. Notice how we use use @EndpointInject
to inject a Camel endpoint into our code then the Mock API to add an expectation on a specific message.
Code Block | ||
---|---|---|
| ||
@ContextConfiguration
public class MyCamelTest extends AbstractJUnit38SpringContextTests {
@Autowired
protected CamelContext camelContext;
@EndpointInject(uri = "mock:foo")
protected MockEndpoint foo;
public void testMocksAreValid() throws Exception {
// lets add more expectations
foo.message(0).header("bar").isEqualTo("ABC");
MockEndpoint.assertIsSatisfied(camelContext);
}
}
|
Further
...
Processing the
...
Received Messages
Sometimes once a Mock endpoint has received some messages you want to then process them further to add further assertions that your test case worked as you expect.
So you can then process the received message exchanges if you like...
Code Block | ||
---|---|---|
| ||
@ContextConfiguration public class MyCamelTest extends AbstractJUnit38SpringContextTests { @Autowired protected CamelContext camelContext; @EndpointInject(uri = "mock:foo") protected MockEndpoint foo; public void testMocksAreValid() throws Exception { // lets add more expectations... MockEndpoint.assertIsSatisfied(camelContext); // now lets do some further assertions List<Exchange> list = foo.getReceivedExchanges(); for (Exchange exchange : list) { Message in = exchange.getIn(); // ... } } } |
Sending and
...
Receiving Messages
It might be that the Enterprise Integration Patterns you have defined in either Spring XML or using the Java DSL do all of the sending and receiving and you might just work with the Mock endpoints as described above. However sometimes in a test case its useful to explicitly send or receive messages directly.
To send or receive messages you should use the Bean Integration mechanism. For example to send messages inject a a ProducerTemplate
using the the @EndpointInject
annotation then call the various send methods on this object to send a message to an endpoint. To consume messages use the the @MessageDriven
annotation on a method to have the method invoked when a message is received.
Code Block | ||
---|---|---|
| ||
public class Foo { @EndpointInject(uri = "activemq:foo.bar") ProducerTemplate producer; public void doSomething() { // lets send a message! producer.sendBody("<hello>world!</hello>"); } // lets consume messages from the 'cheese' queue @MessageDriven(uri="activemq:cheese") public void onCheese(String name) { // ... } } |
See Also
- A real example test case using Mock and Spring along with its Spring XML
- Bean Integration
- Mock endpoint
- Test endpoint