1

I'm trying to set up a test for a Camel route. My test route reads a binary file and sends it to a translator bean, returning a POJO. Now, I'd like to do some assertions on the POJO to ensure the values that are there match the known values. Standard stuff I think. In the examples I've seen, the body seems to always be a String or primitive type, and a simple assertion can be done on it. However, in my case, it is an object, so I want to get the object somehow.

Here's what I've tried so far:

@Override
protected RouteBuilder createRouteBuilder() throws Exception {
    return new RouteBuilder() {
        @Override
        public void configure() throws Exception {
            from("file:///path/to/dir/of/test/file/?noop=true")
            .bean(TranslatorBean.class)
            .to("mock:test").end();
        }
    };
}

@Test
public void testReadMessage() throws Exception {

    MockEndpoint endpoint = getMockEndpoint("mock:test");

    endpoint.whenAnyExchangeReceived(new Processor() {      
        @Override
        public void process(Exchange exchange) throws Exception {           
            Object body = exchange.getIn().getBody();

            assertIsInstanceOf(MyPOJO.class, body);

            MyPOJO message = (MyPOJO) body;

            assertEquals("Some Field", someValue, message.getSomeField());

            // etc., etc.

        }           
    });


    //If I don't put some sleep here it ends before anything happens
    Thread.sleep(2000);

}

When I run this, it appears that it runs correctly, but when I step through, I can see an assertion fails. For some reason, this does not get reported.

So then I tried inlining my Processor in the route like so:

public void configure() throws Exception {
    .from("file:///path/to/dir/of/test/file/?noop=true")
    .bean(TranslatorBean.class)
    .process(new Processor() {
        //same code as before
     });
}

This kind of works, but with a huge problem. Any assertions that fail still do not get reported by JUnit. Instead, they get caught within Camel, and reported as a CamelExecutionException with absolutely no information about the cause. Only by stepping through the debugger can you determine which assertion failed. Also, this way my entire test is within the configure method instead of in its own test method. I have to include an empty test with a sleep to get it to run. Clearly this is terrible, but I'm sure what the right thing to do here is. It looks like a Processor might not be the correct route, but I'm not seeing the correct way. Any guidance is much appreciated.

Denial
  • 363
  • 1
  • 5
  • 12

2 Answers2

6

If you're looking for a way to retrieve the object itself and perform assertions on it, you want something like:

Product resultProduct = resultEndpoint.getExchanges().get(0).getIn().getBody(Product.class);
assertEquals(expectedEANCode, resultProduct.getEANCode());

Where resultEndPoint is the mock endpoint.

Mathias Müller
  • 22,203
  • 13
  • 58
  • 75
fermin.saez
  • 164
  • 2
  • 5
2

I suggest to start reading from the Apache Camel docs. At the user guide: http://camel.apache.org/user-guide.html there is a link to testing: http://camel.apache.org/testing.html which has a lot of information. Also since you use mock endpoints read about as well: http://camel.apache.org/mock

For example the mock code you have can be done as

MockEndpoint endpoint = getMockEndpoint("mock:test");
mock.allMessages().body().isInstanceOf(MyPojo.class)

Though people often use the exepected methods on a mock endpoint etc For example if you expect 2 messages, and their bodies is in order as:

MockEndpoint mock = getMockEndpoint("mock:result");
mock.expectedBodiesReceived("Hello World", "Bye World");

But check out the mock and testing docs to learn more.

And if you have a copy of Camel in Action book, then read chapter 6, its all about testing with Camel.

Claus Ibsen
  • 56,060
  • 7
  • 50
  • 65
  • 1
    Hello Claus, Thank you very much for the response. I've read quite a bit through your book (which I honestly think is one of the best books I've ever read for learning a new technology), as well as the online docs. The examples for testing the body all seem to be like the "Hello World", "Bye World" example you have just given, where the body is simply a String, so doing expects/asserts on the body as a whole makes sense. My message body is an object, however, and I need to do more involved testing than that. Is there no way to get the body of a message and test some its fields? Tusind tak! – Denial Apr 07 '13 at 15:09