OK, I got that to work by using @UseAdviceWith. Here's my @Before method that 
sets everything up and returns SQL results:

        static List<Map> results = new ArrayList<Map>() {{
                add(new HashMap<String, String>() {{
                        put("foo", "bar");
                }});
        }};

        @Before
        public void before() throws Exception {
                camelContext.setTracing(true);

                ModelCamelContext context = (ModelCamelContext) camelContext;
                RouteDefinition route = context.getRouteDefinition("myRouteId");
                route.adviceWith(context, new RouteBuilder() {
                        @Override
                        public void configure() throws Exception {
                                
interceptSendToEndpoint("sql:*").skipSendToOriginalEndpoint().process(new 
Processor() {
                                        @Override
                                        public void process(Exchange exchange) 
throws Exception {
                                                
exchange.getOut().setBody(results);
                                        }
                                });
                        }
                });
                camelContext.start();
        }

Now in my route, I want to verify the final results. Since it's a .process() 
call, there's no endpoint name to look for and mock. 

.to("sql:select * ...")
.to("log:output")
.process(new Processor() {
        public void process(Exchange exchange) throws Exception {
                List<HashMap> data = (ArrayList<HashMap>) 
exchange.getIn().getBody();
                // create response from data
                exchange.getOut().setBody(response);
        }
});

Is it possible to add a "mock:result" at the end, after .process()?

I tried the following, but no messages are received.

@MockEndpoints // added to class

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

        @Test
        ...
                result.expectedMessageCount(1);

                template.sendBody ...

                MockEndpoint.assertIsSatisfied(camelContext);


On Jun 12, 2014, at 9:33 AM, Claus Ibsen <[email protected]> wrote:

> Hi
> 
> @ EndpointInject does not match wildcards.
> 
> Do this as I said before in my previous mail
> 
> But as the SQL endpoint is dynamic calculated then its easier to use
> interceptSendToEndpoint and skip, as shown in the book on page 182
> with the advice with.
> 
> On Thu, Jun 12, 2014 at 4:47 PM, Matt Raible <[email protected]> wrote:
>> Possibly. If I have the following annotations on my class:
>> 
>> @MockEndpoints("sql:.*")
>> @UseAdviceWith
>> 
>> And I mock the SQL endpoint:
>> 
>>        @EndpointInject(uri = "mock:sql:*")
>>        MockEndpoint mockSql;
>> 
>> Then I try to set the mocked endpoint's results:
>> 
>>        @Test
>>        public void testMockSQLEndpoint() throws Exception {
>>                mockSql.whenAnyExchangeReceived(new Processor() {
>>                        @Override
>>                        public void process(Exchange exchange) throws 
>> Exception {
>>                                exchange.getIn().setBody("sql output");
>>                        }
>>                });
>>                camelContext.start();
>> 
>> The mock SQL output is still not set.
>> 
>> On Jun 12, 2014, at 8:40 AM, Claus Ibsen <[email protected]> wrote:
>> 
>>> Hi
>>> 
>>> Is it the @AdviceWith you are looking for ?
>>> http://camel.apache.org/spring-testing.html
>>> 
>>> On Thu, Jun 12, 2014 at 4:30 PM, Matt Raible <[email protected]> wrote:
>>>> Is it possible to use adviceWith when using Spring/Camel's annotation 
>>>> support? I was originally trying to use this method, but had to extend 
>>>> CamelTestSupport and its context did not have my routes in it.
>>>> 
>>>> On Jun 11, 2014, at 11:39 PM, Claus Ibsen <[email protected]> wrote:
>>>> 
>>>>> Hi
>>>>> 
>>>>> You may want to use @MockEndpointsAndSkip so you do not call the SQL 
>>>>> component.
>>>>> 
>>>>> The camel-spring-test with the annotations was added to Camel later,
>>>>> after the book was published.
>>>>> 
>>>>> But you can find the annotations and more details here
>>>>> http://camel.apache.org/spring-testing.html
>>>>> 
>>>>> But as the SQL endpoint is dynamic calculated then its easier to use
>>>>> interceptSendToEndpoint and skip, as shown in the book on page 182
>>>>> with the advice with.
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> On Thu, Jun 12, 2014 at 1:58 AM, Matt Raible <[email protected]> 
>>>>> wrote:
>>>>>> Nope, my routes are defined using the Java DSL, not XML. Changing from:
>>>>>> 
>>>>>> @ContextConfiguration(classes = CamelConfig.class)
>>>>>> 
>>>>>> To:
>>>>>> 
>>>>>> @ContextConfiguration(loader = 
>>>>>> CamelSpringDelegatingTestContextLoader.class, classes = 
>>>>>> CamelConfig.class)
>>>>>> 
>>>>>> Solved my problem.
>>>>>> 
>>>>>> I don't know if the regex needs to change. Using 
>>>>>> @MockEndpoints("sql:*"), I see the following in my logs:
>>>>>> 
>>>>>> 2014-06-11 17:53:35,388 [main           ] INFO  output                   
>>>>>>       - Exchange[ExchangePattern: InOnly, BodyType: java.util.ArrayList, 
>>>>>> Body: []]
>>>>>> 2014-06-11 17:53:35,389 [main           ] INFO  MockEndpoint             
>>>>>>       - Asserting: Endpoint[mock://sql:select...] is satisfied
>>>>>> 2014-06-11 17:53:35,390 [main           ] INFO  MockEndpoint             
>>>>>>       - Asserting: Endpoint[mock://sql:*] is satisfied
>>>>>> 
>>>>>> It looks like it's working, but the test is failing:
>>>>>> 
>>>>>> java.lang.AssertionError: mock://sql:* Received message count. Expected: 
>>>>>> <1> but was: <0>
>>>>>> 
>>>>>> So now I want to do two things: 1) understand why my mockSQL endpoint is 
>>>>>> not receiving a message and 2) make the mock SQL endpoint return an 
>>>>>> ArrayList of items so I can test my processing logic.
>>>>>> 
>>>>>> On Jun 11, 2014, at 5:46 PM, Minh Tran <[email protected]> wrote:
>>>>>> 
>>>>>>> It appears to me like you have your routes defined in xml and not 
>>>>>>> actually in JavaConfig? In that case, you can simplify your 
>>>>>>> configuration even further and not refer to your JavaConfig class like 
>>>>>>> this
>>>>>>> 
>>>>>>> @RunWith(CamelSpringJUnit4ClassRunner.class)
>>>>>>> @ContextConfiguration(loader = 
>>>>>>> CamelSpringDelegatingTestContextLoader.class, locations = { 
>>>>>>> "classpath:/path/to/xml" })
>>>>>>> @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
>>>>>>> @MockEndpointsAndSkip("sql:.*")
>>>>>>> public class FooRouteTests
>>>>>>> 
>>>>>>> No need to extend any class.
>>>>>>> Also your regex has to be "sql:.*" and not "sql:*" They mean two 
>>>>>>> different things in regex.
>>>>>>> 
>>>>>>> On 12/06/2014, at 9:32 AM, Matt Raible <[email protected]> wrote:
>>>>>>> 
>>>>>>>> Thanks for your advice. Here's my attempt to modify my test to use 
>>>>>>>> CamelSpringJUnit4ClassRunner and annotations to mock my SQL endpoint.
>>>>>>>> 
>>>>>>>> @RunWith(CamelSpringJUnit4ClassRunner.class)
>>>>>>>> @ContextConfiguration(classes = CamelConfig.class)
>>>>>>>> @DirtiesContext(classMode = 
>>>>>>>> DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
>>>>>>>> @MockEndpoints("sql:*")
>>>>>>>> public class FooRouteTests {
>>>>>>>> 
>>>>>>>>   @Autowired
>>>>>>>>   CamelContext camelContext;
>>>>>>>> 
>>>>>>>>   @Produce
>>>>>>>>   ProducerTemplate template;
>>>>>>>> 
>>>>>>>>   @EndpointInject(uri = "mock:sql:*")
>>>>>>>>   MockEndpoint mockSql;
>>>>>>>> 
>>>>>>>>   @Test
>>>>>>>>   public void testMockSQLEndpoint() throws Exception {
>>>>>>>>           template.sendBody("direct:foo", "bar");
>>>>>>>> 
>>>>>>>>           mockSql.expectedMessageCount(1);
>>>>>>>>            // todo: take input message and return mock results 
>>>>>>>> (ArrayList<HashMap>)
>>>>>>>>           MockEndpoint.assertIsSatisfied(camelContext);
>>>>>>>>   }
>>>>>>>> }
>>>>>>>> 
>>>>>>>> For some reason, this results in an error, even though my CamelConfig 
>>>>>>>> works for configuring other tests.
>>>>>>>> 
>>>>>>>> Could not autowire field: org.apache.camel.CamelContext 
>>>>>>>> com.company.app.foo.FooRouteTests.camelContext; nested exception is 
>>>>>>>> org.springframework.beans.factory.NoSuchBeanDefinitionException: No 
>>>>>>>> qualifying bean of type [org.apache.camel.CamelContext] found for 
>>>>>>>> dependency: expected at least 1 bean which qualifies as autowire 
>>>>>>>> candidate for this dependency.
>>>>>>>> 
>>>>>>>> @Configuration
>>>>>>>> @ImportResource("classpath:META-INF/cxf/cxf.xml")
>>>>>>>> @ComponentScan("com.company.app")
>>>>>>>> public class CamelConfig extends CamelConfiguration {
>>>>>>>> 
>>>>>>>>   @Override
>>>>>>>>   protected void setupCamelContext(CamelContext camelContext) throws 
>>>>>>>> Exception {
>>>>>>>>           PropertiesComponent pc = new PropertiesComponent();
>>>>>>>>           pc.setLocation("classpath:application.properties");
>>>>>>>>           camelContext.addComponent("properties", pc);
>>>>>>>>           super.setupCamelContext(camelContext);
>>>>>>>>   }
>>>>>>>> }
>>>>>>>> 
>>>>>>>> 
>>>>>>>> On Jun 11, 2014, at 5:08 PM, Minh Tran <[email protected]> 
>>>>>>>> wrote:
>>>>>>>> 
>>>>>>>>> If you're using Spring, I recommend not extending any of the Camel 
>>>>>>>>> Test classes and using the Camel Enhanced Spring Test as described 
>>>>>>>>> here
>>>>>>>>> http://camel.apache.org/spring-testing.html
>>>>>>>>> 
>>>>>>>>> The docs take a bit of getting use to because it describes several 
>>>>>>>>> different ways of testing via Spring but you just have to skip to the 
>>>>>>>>> Camel Enhanced Spring Test bits. It also doesn't describe how to test 
>>>>>>>>> using a JavaConfig class very well IMO. It only describes how to do 
>>>>>>>>> this by extending AbstractJUnit4SpringContextTests which is a really 
>>>>>>>>> old way of doing spring unit tests. I had to do a lot of 
>>>>>>>>> experimenting to get it to work without extending this class.
>>>>>>>>> 
>>>>>>>>> Here's an example I had, the only difference is my JavaConfig is 
>>>>>>>>> embedded into my unit test class, but there's no reason you couldn't 
>>>>>>>>> refer to an existing class. If you want to mock and skip your sql or 
>>>>>>>>> soap calls, then instead of using @MockEndPoints, use 
>>>>>>>>> @MockEndPointsAndSkip.  Look further down to see some gotchas that I 
>>>>>>>>> encountered in all of this.
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> @RunWith(CamelSpringJUnit4ClassRunner.class)
>>>>>>>>> @ContextConfiguration(loader = 
>>>>>>>>> CamelSpringDelegatingTestContextLoader.class, classes = 
>>>>>>>>> RegexTest.JavaConfig.class)
>>>>>>>>> @MockEndpoints
>>>>>>>>> @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
>>>>>>>>> public class RegexTest {
>>>>>>>>> 
>>>>>>>>>  @Produce(uri = "direct:start")
>>>>>>>>>  private ProducerTemplate producerTemplate;
>>>>>>>>> 
>>>>>>>>>  @EndpointInject(uri = "mock:direct:match")
>>>>>>>>>  private MockEndpoint matchEndpoint;
>>>>>>>>> 
>>>>>>>>>  @EndpointInject(uri = "mock:direct:nomatch")
>>>>>>>>>  private MockEndpoint noMatchEndpoint;
>>>>>>>>> 
>>>>>>>>>  @Configuration
>>>>>>>>>  public static class JavaConfig extends SingleRouteCamelConfiguration 
>>>>>>>>> {
>>>>>>>>> 
>>>>>>>>>          @Override
>>>>>>>>>          public RouteBuilder route() {
>>>>>>>>>                  return new RouteBuilder() {
>>>>>>>>> 
>>>>>>>>>                          @Override
>>>>>>>>>                          public void configure() throws Exception {
>>>>>>>>>                                  
>>>>>>>>> from("direct:start").to("log:blah?showProperties=true").log("${property.scaleResponse.message}").choice().when()
>>>>>>>>>                                                  
>>>>>>>>> .simple("resource:classpath:simple/item_not_exists.txt").to("direct:match").otherwise().to("direct:nomatch").end();
>>>>>>>>>                                  from("direct:match").log("matched");
>>>>>>>>>                                  from("direct:nomatch").log("no 
>>>>>>>>> match");
>>>>>>>>>                                  this.getContext().setTracing(true);
>>>>>>>>>                          }
>>>>>>>>>                  };
>>>>>>>>>          }
>>>>>>>>>  }
>>>>>>>>> 
>>>>>>>>>  @After
>>>>>>>>>  public void afterTest() throws InterruptedException {
>>>>>>>>>          matchEndpoint.assertIsSatisfied();
>>>>>>>>>          noMatchEndpoint.assertIsSatisfied();
>>>>>>>>>  }
>>>>>>>>> 
>>>>>>>>>  @Test
>>>>>>>>>  public void testMatch() {
>>>>>>>>>          InterfaceResponse response = new InterfaceResponse();
>>>>>>>>>          response.setMessage("ITEM XML Download  ended. : Item 
>>>>>>>>> \"blah\" does not exist. - ");
>>>>>>>>>          matchEndpoint.expectedMessageCount(1);
>>>>>>>>> 
>>>>>>>>>          producerTemplate.sendBodyAndProperty(null, "scaleResponse", 
>>>>>>>>> response);
>>>>>>>>> 
>>>>>>>>>  }
>>>>>>>>> 
>>>>>>>>> }
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> The regex you provide to mockendpointandskip  and mock endpoint is 
>>>>>>>>> important to get right. I didn't add any regex to my example above 
>>>>>>>>> because mocking all endpoints (the default) was ok in my example. if 
>>>>>>>>> you get this regex wrong, camel doesn't warn you. You can turn on 
>>>>>>>>> camel logging to see whether it has mocked your endpoint correctly or 
>>>>>>>>> not. It should say something like the following. That's how you know 
>>>>>>>>> it is working.
>>>>>>>>> 
>>>>>>>>> INFO  org.apache.camel.impl.InterceptSendToMockEndpointStrategy - 
>>>>>>>>> Adviced endpoint [direct://start] with mock endpoint 
>>>>>>>>> [mock:direct:start]
>>>>>>>>> 
>>>>>>>>> The regex value matching is a bit strange, if it doesn't match your 
>>>>>>>>> endpoint even though you are absolutely sure it is correct, try 
>>>>>>>>> tacking on ".*" on the end of it, this fixed it up for me many times. 
>>>>>>>>> IMO I think it's a bug in the camel regex matching somewhere.
>>>>>>>>> 
>>>>>>>>> When you do the @EndpointInject uri, make sure you prepend with 
>>>>>>>>> "mock" and don't include anything pass the "?" in your uri. This 
>>>>>>>>> wasn't obvious to me. And again camel won't warn you if you get this 
>>>>>>>>> wrong.
>>>>>>>>> 
>>>>>>>>> @DirtiesContext is a must otherwise you get strange behaviour once 
>>>>>>>>> one test starts failing.
>>>>>>>>> 
>>>>>>>>> Hope that helps.
>>>>>>>>> 
>>>>>>>>> On 12/06/2014, at 8:27 AM, Matt Raible <[email protected]> wrote:
>>>>>>>>> 
>>>>>>>>>> Thanks for the advice. I bought the book, read chapter 6 and I'm 
>>>>>>>>>> trying to use the advice builder. Chapter 6 talks about using mocks 
>>>>>>>>>> quite a bit, which seems useful in building a route, but not when 
>>>>>>>>>> it's already built.
>>>>>>>>>> 
>>>>>>>>>> My routes are configured with Spring and JavaConfig in a CamelConfig 
>>>>>>>>>> class. When I try to use CamelTestSupport as my parent class, the 
>>>>>>>>>> context doesn't have any route definitions in it. In other words, 
>>>>>>>>>> context.getRouteDefinitions() returns an empty list. How do I get 
>>>>>>>>>> CamelTestSupport to recognize my routes configured in Spring? Or is 
>>>>>>>>>> it possible to inject the context and template and use adviceWith 
>>>>>>>>>> w/o extending CamelTestSupport?
>>>>>>>>>> 
>>>>>>>>>> Thanks,
>>>>>>>>>> 
>>>>>>>>>> Matt
>>>>>>>>>> 
>>>>>>>>>> @RunWith(SpringJUnit4ClassRunner.class)
>>>>>>>>>> @ContextConfiguration(classes = CamelConfig.class)
>>>>>>>>>> public class FooRouteTests extends CamelTestSupport {
>>>>>>>>>> 
>>>>>>>>>> @Test
>>>>>>>>>> public void testAdvised() throws Exception {
>>>>>>>>>>         context.getRouteDefinition("routeId").adviceWith(context, 
>>>>>>>>>> new RouteBuilder() {
>>>>>>>>>>                 @Override
>>>>>>>>>>                 public void configure() throws Exception {
>>>>>>>>>>                         // intercept sending to mock:foo and do 
>>>>>>>>>> something else
>>>>>>>>>>                         interceptSendToEndpoint("sql:*")
>>>>>>>>>>                                         .skipSendToOriginalEndpoint()
>>>>>>>>>>                                         .to("log:foo")
>>>>>>>>>>                                         .to("mock:advised");
>>>>>>>>>>                 }
>>>>>>>>>>         });
>>>>>>>>>>         // we must manually start when we are done with all the 
>>>>>>>>>> advice with
>>>>>>>>>>         context.start();
>>>>>>>>>> 
>>>>>>>>>>         template.sendBody("direct:foo", "bar");
>>>>>>>>>> 
>>>>>>>>>>         getMockEndpoint("mock:advised").expectedMessageCount(1);
>>>>>>>>>>         assertMockEndpointsSatisfied();
>>>>>>>>>> }
>>>>>>>>>> 
>>>>>>>>>> @Override
>>>>>>>>>> public boolean isUseAdviceWith() {
>>>>>>>>>>         // tell we are using advice with, which allows us to advice 
>>>>>>>>>> the route
>>>>>>>>>>         // before Camel is being started, and thus can replace sql 
>>>>>>>>>> with something else.
>>>>>>>>>>         return true;
>>>>>>>>>> }
>>>>>>>>>> 
>>>>>>>>>> On Jun 11, 2014, at 12:16 PM, Claus Ibsen <[email protected]> 
>>>>>>>>>> wrote:
>>>>>>>>>> 
>>>>>>>>>>> Hi
>>>>>>>>>>> 
>>>>>>>>>>> Yeah if you have Camel in Action book, read chapter 6.
>>>>>>>>>>> 
>>>>>>>>>>> And see bottom of this page
>>>>>>>>>>> http://camel.apache.org/testing
>>>>>>>>>>> 
>>>>>>>>>>> The advice builder is quite nifty and can "rework" the routes 
>>>>>>>>>>> before testing.
>>>>>>>>>>> 
>>>>>>>>>>> 
>>>>>>>>>>> On Wed, Jun 11, 2014 at 8:10 PM, Matt Raible 
>>>>>>>>>>> <[email protected]> wrote:
>>>>>>>>>>>> Hello,
>>>>>>>>>>>> 
>>>>>>>>>>>> I have a route that looks as follows:
>>>>>>>>>>>> 
>>>>>>>>>>>>         from(uri)
>>>>>>>>>>>>                         .to("log:input")
>>>>>>>>>>>>                         
>>>>>>>>>>>> .recipientList(simple("direct:${header.operationName}"));
>>>>>>>>>>>>         from("direct:lookup")
>>>>>>>>>>>>                         .process(new Processor() {
>>>>>>>>>>>>                                 public void process(Exchange 
>>>>>>>>>>>> exchange) throws Exception {
>>>>>>>>>>>>                                         // grab parameters from 
>>>>>>>>>>>> request and set as headers for SQL statement
>>>>>>>>>>>>                                 }
>>>>>>>>>>>>                         })
>>>>>>>>>>>>                         
>>>>>>>>>>>> .recipientList(simple("sql:{{sql.lookup}}")).delimiter("false")
>>>>>>>>>>>>                         .to("log:output")
>>>>>>>>>>>>                         .process(new Processor() {
>>>>>>>>>>>>                                 public void process(Exchange 
>>>>>>>>>>>> exchange) throws Exception {
>>>>>>>>>>>>                                         List<HashMap> data = 
>>>>>>>>>>>> (ArrayList<HashMap>) exchange.getIn().getBody();
>>>>>>>>>>>> 
>>>>>>>>>>>>                                         // convert data to response
>>>>>>>>>>>> 
>>>>>>>>>>>>                                         
>>>>>>>>>>>> exchange.getOut().setBody(response);
>>>>>>>>>>>>                                 }
>>>>>>>>>>>>                         })
>>>>>>>>>>>> 
>>>>>>>>>>>> Is it possible to unit test this route and mock the data returned 
>>>>>>>>>>>> from the "sql" call? It'd love to be able to verify headers after 
>>>>>>>>>>>> the first .process, mock the results from the SQL call and verify 
>>>>>>>>>>>> the results from the 2nd .process method.
>>>>>>>>>>>> 
>>>>>>>>>>>> All of the routes I've developed with Camel so far make SQL calls, 
>>>>>>>>>>>> but I see SOAP calls in the future. I'll eventually need to mock 
>>>>>>>>>>>> SOAP calls as well.
>>>>>>>>>>>> 
>>>>>>>>>>>> Thanks,
>>>>>>>>>>>> 
>>>>>>>>>>>> Matt
>>>>>>>>>>> 
>>>>>>>>>>> 
>>>>>>>>>>> 
>>>>>>>>>>> --
>>>>>>>>>>> Claus Ibsen
>>>>>>>>>>> -----------------
>>>>>>>>>>> Red Hat, Inc.
>>>>>>>>>>> Email: [email protected]
>>>>>>>>>>> Twitter: davsclaus
>>>>>>>>>>> Blog: http://davsclaus.com
>>>>>>>>>>> Author of Camel in Action: http://www.manning.com/ibsen
>>>>>>>>>>> hawtio: http://hawt.io/
>>>>>>>>>>> fabric8: http://fabric8.io/
>>>>>>>>>> 
>>>>>>>>> 
>>>>>>>> 
>>>>>>> 
>>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> --
>>>>> Claus Ibsen
>>>>> -----------------
>>>>> Red Hat, Inc.
>>>>> Email: [email protected]
>>>>> Twitter: davsclaus
>>>>> Blog: http://davsclaus.com
>>>>> Author of Camel in Action: http://www.manning.com/ibsen
>>>>> hawtio: http://hawt.io/
>>>>> fabric8: http://fabric8.io/
>>>> 
>>> 
>>> 
>>> 
>>> --
>>> Claus Ibsen
>>> -----------------
>>> Red Hat, Inc.
>>> Email: [email protected]
>>> Twitter: davsclaus
>>> Blog: http://davsclaus.com
>>> Author of Camel in Action: http://www.manning.com/ibsen
>>> hawtio: http://hawt.io/
>>> fabric8: http://fabric8.io/
>> 
> 
> 
> 
> -- 
> Claus Ibsen
> -----------------
> Red Hat, Inc.
> Email: [email protected]
> Twitter: davsclaus
> Blog: http://davsclaus.com
> Author of Camel in Action: http://www.manning.com/ibsen
> hawtio: http://hawt.io/
> fabric8: http://fabric8.io/

Reply via email to