2

How do I replace a heavy-weight input endpoint with a mock and send a message to it?

Say I have the following route.

from("spring-ws:rootqname:{http://myNameSpace}SomeRequest?endpointMapping=#endpointMapping").
    processor(new VeryComplicatedProcessor()).
    to(etc).
    to(etc)...

In other words, a spring web service that does a whole lotta processing.

One way to test this route is to start up the webservice in a webserver and send it a message, but that's a lot more overhead than I'd like to incur.

Instead, I'd expect that if I mock all of my endpoints, I should be able to do this:

public class RouteTest extends CamelSpringTestSupport {

    @Override
    public String isMockEndpoints() {
        return "*";   // mock everything
    }

    @Test
    public void simpleDirectTest() throws Exception {

        String realURI = "spring-ws:rootqname:{http://myNameSpace}SomeRequest?endpointMapping=#endpointMapping";
        String mockedURI = "mock:" + realURI;
        String msg = buildSomeSoapMsg();

        Object out = template.requestBody(mockedURI, msg);
        log.debug(out.toString());
    }
...
}

... and have the entire route run and return the response to me. Instead though, I just get the message sent right back to me, and the route hasn't been run.

Is my understanding of mocks incorrect? If so is there an alternative way to achieve this? I'd really like to avoid having to actually start the webservice to test these routes.

Thanks all.

EDIT - It looked for a minute like I could use AdviceWith to solve this problem, but AdviceWith only seems to work with outputs, and not inputs as is the case above.

Community
  • 1
  • 1
Roy Truelove
  • 22,016
  • 18
  • 111
  • 153

2 Answers2

2

In Apache Camel 2.9 there is a new replaceFrom method in the advice with, which allows you to replace a consumer before unit testing with some other endpoint. For example you could replace the spring-ws with a direct endpoint. And then send a message to that direct endpoint in your unit test. On the same line as what Ben posted above in his answer. See details at: http://camel.apache.org/advicewith.html

Claus Ibsen
  • 56,060
  • 7
  • 50
  • 65
  • Thanks Claus, good news. Thanks for all the hard work over there! – Roy Truelove Aug 19 '11 at 13:43
  • btw I just renamed the method to replaceFromWith, to better indicate its replacing the from endpoint *with* something else. – Claus Ibsen Aug 19 '11 at 17:17
  • And if you override the isUseAdviceWith() method and return true, then you dont need camel-spring-ws on the classpath as Camel is not started before the advice code. I added details about this to that link above. – Claus Ibsen Aug 19 '11 at 17:18
1

you have a few options...if you are just trying to test the rest of the route (from VeryComplicatedProcessor on), then you can split up the route so that you can test it using direct, etc...

from("spring-ws:rootqname:  {http://myNameSpace}SomeRequest?endpointMapping=#endpointMapping").
.to("direct:processRequest");

from("direct:processRequest").
processor(new VeryComplicatedProcessor()).
to(etc).
to(etc)...

Another option is to just standup the webservice in the unit test and use HTTP client APIs to simulate requests to the real route. See the camel-spring-ws examples

Finally, if you really need to replace an endpoint for a test, then use properties to override the endpoint definition or adviceWith or intercept strategies to give you even more flexibility (though can be confusing at first)...

Ben ODay
  • 20,784
  • 9
  • 45
  • 68
  • Thanks boday, I ended up doing the former, splitting up the services and using the direct. Surprised that sending to a mock doesn't do the trick though.. – Roy Truelove Aug 12 '11 at 21:44
  • cool...the mock is a bit confusing at first, think of it as a destination endpoint to dump messages to for validation – Ben ODay Aug 12 '11 at 22:20