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/

Reply via email to