17 sept. 2015

Apache Camel - Unit Testing Spring route

Apache Camel is an awesome framework, also providing a unit testing framework.

I found it quite tough to dive into that testing framework as testing a route is not the same than testing a regular Java class.
Here are some pattern when testing your Spring route :

Base code

The spring route

Assuming this route in camel.xml :

 

 
  
 

 

 
 

Test class skeleton

And this JUnit test class, referencing
  1. The XML route file
  2. The @DirtiesContext allowing us to manipulate the Camel Context on tests without effects outside of each test
   
@ContextConfiguration("classpath:camel.xml")
@DirtiesContext
public class MyTest extends AbstractJUnit4SpringContextTests{

    @Autowired
    private ModelCamelContext context;

    @Test
    public void testRouteId() throws Exception {
       // introspect route
       // create expectations
       // execute route
       // asserts
    }
}

Patterns to test the route

Test a component

Here we are mocking the parameters provided to the WebService :
  1. Create a MockEndpoint
  2. Insert endpoint in the route
  3. Add expectations for the endpoint :
    1. The number of messages
    2. The type of the message
    3. The content of the message
  4. At the end of the test method, trigger the assertion

    @EndpointInject(uri = "mock:assertWsParams")
    protected MockEndpoint assertWsParams;
...

//introspection
context.getRouteDefinition("route-id").adviceWith(context, new AdviceWithRouteBuilder() {
 @Override
 public void configure() throws Exception {
  weaveById("cxfWs").before().to(assertWsParams);
 }
});

//expectations
assertWsParams.expectedMessageCount(1);
assertWsParams.expectedBodyReceived().body().isInstanceOf(RequestType.class);
assertWsParams.expectedMessagesMatches(new Predicate() {
 @Override
 public boolean matches(Exchange exchange) {
  return ((RequestType) exchange.getIn().getBody()).getId().equals(EXPECTED_ID);
 }
});

//execution
...

//assertion
assertWsParams.assertIsSatisfied();

Mock a component

Here we are mocking the cxf WebService with a static response :
  1. Find the "node" with the weaveById
  2. replace() it
  3. with a process()
context.getRouteDefinition("route-id").adviceWith(context, new AdviceWithRouteBuilder() {
 @Override
 public void configure() throws Exception {
  weaveById("cxfWs").replace().process(new Processor() {
   @Override
   public void process(Exchange exchange) throws Exception {
    ReponseType res = new ResponseType();
    res.setCode("200");
    res.setMessage("OK");
    exchange.getOut().setBody(res);
   }
  }).id("cxfWsMock");
 }
});

Run the test

Here we are running the test, injecting some data in the route to test it and the assertions :
  1. Create a producer on a uri
  2. Send some data
@Produce(uri = "direct:hello")
protected ProducerTemplate producer;
...

producer.sendBody("Hello");

Conclusion

My tests are mainly based on these 3 patterns, be sure to understand the logic.

More information on Camel test documentation

0 commentaires:

Enregistrer un commentaire

Fourni par Blogger.