You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by dunnlow <du...@yahoo.com> on 2011/08/05 01:43:15 UTC

noob spring testing question

I'm new to Camel (and relatively new to Spring).  I've got a route with a
bean up and running but I want to perform some unit testing.  I'm trying to
figure out how to "feed" my test with XML that is contained in a file.  

My working app has a bean with a method to load XML into the header
parameters and a method to create SQL from the header parameters:

This route works for me in my application:
<camel:route>
   <camel:from uri="file:/archive/inbox/>
   <camel:bean ref="myEventBean" method="fromXML"/>
   <camel:bean ref="myEventBean" method="toJdbc"/>
   <camel:to uri="jdbc:dataSource"/>
</camel:route>

I'm trying to create an XML file that I can tweak to make sure that the
bean's methods hold up regardless of the XML passed (it comes from JMS
queues and files and there is a lot of error checking to make sure the
resulting jdbc query is valid).

Seems like it should be easy enough.  Here is my test to read the file and
see the query produced.  The first one (testMocksAreValid) works.  I'm
trying to figure out the second Test which causes the Exception:
org.apache.camel.CamelExecutionException: Exception occurred during
execution on the exchange: Exchange[Message:
file://src/test/resources/inbox/?noop=true]
...8<...
Caused by: org.apache.camel.builder.xml.InvalidXPathExtression: Invalid
xpth: //event/@topic.  Reason: javax.xml.xpath.XPathExpressionException

*Note, because this exact XML file works in my application, I'm assuming the
problem is with the way I am consuming it...
-------------
public class myEventBeanTest extends
org.apache.camel.test.junit4.CamelSpringTestSupport{
  @EndpointInject(uri="mock:result")
   protected MockEndpoint resultEndpoint;

  @Produce(uri="direct:start")
  protected ProducerTemplate template

  @Autowired
  protected CamelContext camelContext;

  @Test
  public void testMocksAreValid() throws Exception{
     MockEndPoint.assertIsSatisfied(camelContext);
  }

  public void setUp() throws Exception{
      super.setUp();
  }

  protected AbstractXmlApplicationContext createApplicationContext(){
      return new
ClasspathXmlApplicationContext("myEventBeanTest-context.xml"};
  }

  @Override
  protected RouteBuilder createRouteBuilder() throws Exception{
     return new RouteBuilder(){
          @Override
          public void configure() throws Exception{
               
from("direct:start").beanRef("myEventBean","fromXML").beanRef("myEventBean","toJdbc").to("stream:out");
          }

  @Test
  public void secondTest() throws Exception{
       Thread.sleep(3000);
       template.sendBody("file://src/test/resources/inbox/?noop=true"); 
<------????
  }

------------------------

fyi, I am injecting the route because I want to use the same context
file/content that my live application has.

I'm sure this is based upon some fundamental misunderstanding, but I'm
stuck.  I think I can see that I need to read the xml file into body.  I've
trying moving the file endpoint up into the route, but then am not sure how
to kick the whole thing off.

Which leads me to my questions (whew):


1) What magic do i need to work to feed the XML file?

2) My noop option on the File component isn't working - the file gets
deleted each time I run the test - anybody know why?

3) I have read the api/javadocs on sendBody, sendBodyAndHeader, etc, but I'm
having a hard time finding good explanations of what they do and how to use
them (I have Camel in Action, which has been a big help except for this). 
Can someone point me to a more thorough explanation/tutorial of using the
producer template?...better than
http://camel.apache.org/producertemplate.html  :)


Thanks for any insight!
 -J

--
View this message in context: http://camel.465427.n5.nabble.com/noob-spring-testing-question-tp4668163p4668163.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: noob spring testing question

Posted by Taariq Levack <ta...@gmail.com>.
Ah, makes sense.
Great that it works, enjoy the ride.

On Fri, Aug 5, 2011 at 4:26 PM, dunnlow <du...@yahoo.com> wrote:
> Taariq, my bad.  The version of the code I entered was not the exact version
> to which I was referring -a symptom of trying so many different things.  I'm
> guessing the issue was with the fact that once I passed something to the
> route, it was no longer considered a consumer?  Anyway, using the noop in
> the full route in the app (as well as in the InputStream method in my test,
> of course), all is working.  Thanks again and sorry for the confusion.
> -J
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/noob-spring-testing-question-tp4668163p4669678.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>

Re: noob spring testing question

Posted by dunnlow <du...@yahoo.com>.
Taariq, my bad.  The version of the code I entered was not the exact version
to which I was referring -a symptom of trying so many different things.  I'm
guessing the issue was with the fact that once I passed something to the
route, it was no longer considered a consumer?  Anyway, using the noop in
the full route in the app (as well as in the InputStream method in my test,
of course), all is working.  Thanks again and sorry for the confusion.
-J

--
View this message in context: http://camel.465427.n5.nabble.com/noob-spring-testing-question-tp4668163p4669678.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: noob spring testing question

Posted by Taariq Levack <ta...@gmail.com>.
Forgive the ambiguity, it should be set on the consumer, but it's not set on the consumer in your code. [1]
I don't know about your logging, you might have another config for test, or try a breakpoint on the send. But you want to send a file, not a string that points to the file.

[1] <camel:from uri="file:/archive/inbox/>

Taariq

On 05 Aug 2011, at 2:01 PM, dunnlow <du...@yahoo.com> wrote:

> Taariq,
> Thanks for getting back.  Can you explain your point for #2.  When I look at
> the documentation for the file component
> (http://camel.apache.org/file2.html) I read it to say that the noop option
> IS on the consumer.  A route that starts with
> from("file://inbox/?noop=true") wont leave the file alone?  What is the
> right way to do this?  
> 
> Also, interestingly, I get tracer information for my application but not
> when I run my test.  It is enabled in both cases with xml in my context
> file:  <camel:camelContext id="camel" trace="true">.  I suppose things are
> failing before it gets to the tracer?
> 
> Thanks again, 
> -J
> 
> --
> View this message in context: http://camel.465427.n5.nabble.com/noob-spring-testing-question-tp4668163p4669371.html
> Sent from the Camel - Users mailing list archive at Nabble.com.

Re: noob spring testing question

Posted by dunnlow <du...@yahoo.com>.
Taariq,
Thanks for getting back.  Can you explain your point for #2.  When I look at
the documentation for the file component
(http://camel.apache.org/file2.html) I read it to say that the noop option
IS on the consumer.  A route that starts with
from("file://inbox/?noop=true") wont leave the file alone?  What is the
right way to do this?  

Also, interestingly, I get tracer information for my application but not
when I run my test.  It is enabled in both cases with xml in my context
file:  <camel:camelContext id="camel" trace="true">.  I suppose things are
failing before it gets to the tracer?

Thanks again, 
-J

--
View this message in context: http://camel.465427.n5.nabble.com/noob-spring-testing-question-tp4668163p4669371.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: noob spring testing question

Posted by Taariq Levack <ta...@gmail.com>.
Hi

1. You are sending to direct:start a String, not a file/folder to consume from. If you turn on trace I'm sure this is what you'll see.
So you don't need magic, you're already consuming the file using the XML route, but if you want to feed some other XML instead then you can use the producer to either write XML to that folder or send it to a new route which tests your beans in isolation.

2. Noop isn't set on the consumer in the XML, so it can't work,
And when you do set it, your string has no effect.

3. Maybe when you see what you're producing in 1. you get a better picture, but it simply sends a body and maybe header/s to some endpoint, just many variations in the API.

Check out the chapter on testing for inspiration.

Taariq

On 05 Aug 2011, at 1:43 AM, dunnlow <du...@yahoo.com> wrote:

> I'm new to Camel (and relatively new to Spring).  I've got a route with a
> bean up and running but I want to perform some unit testing.  I'm trying to
> figure out how to "feed" my test with XML that is contained in a file.  
> 
> My working app has a bean with a method to load XML into the header
> parameters and a method to create SQL from the header parameters:
> 
> This route works for me in my application:
> <camel:route>
>   <camel:from uri="file:/archive/inbox/>
>   <camel:bean ref="myEventBean" method="fromXML"/>
>   <camel:bean ref="myEventBean" method="toJdbc"/>
>   <camel:to uri="jdbc:dataSource"/>
> </camel:route>
> 
> I'm trying to create an XML file that I can tweak to make sure that the
> bean's methods hold up regardless of the XML passed (it comes from JMS
> queues and files and there is a lot of error checking to make sure the
> resulting jdbc query is valid).
> 
> Seems like it should be easy enough.  Here is my test to read the file and
> see the query produced.  The first one (testMocksAreValid) works.  I'm
> trying to figure out the second Test which causes the Exception:
> org.apache.camel.CamelExecutionException: Exception occurred during
> execution on the exchange: Exchange[Message:
> file://src/test/resources/inbox/?noop=true]
> ...8<...
> Caused by: org.apache.camel.builder.xml.InvalidXPathExtression: Invalid
> xpth: //event/@topic.  Reason: javax.xml.xpath.XPathExpressionException
> 
> *Note, because this exact XML file works in my application, I'm assuming the
> problem is with the way I am consuming it...
> -------------
> public class myEventBeanTest extends
> org.apache.camel.test.junit4.CamelSpringTestSupport{
>  @EndpointInject(uri="mock:result")
>   protected MockEndpoint resultEndpoint;
> 
>  @Produce(uri="direct:start")
>  protected ProducerTemplate template
> 
>  @Autowired
>  protected CamelContext camelContext;
> 
>  @Test
>  public void testMocksAreValid() throws Exception{
>     MockEndPoint.assertIsSatisfied(camelContext);
>  }
> 
>  public void setUp() throws Exception{
>      super.setUp();
>  }
> 
>  protected AbstractXmlApplicationContext createApplicationContext(){
>      return new
> ClasspathXmlApplicationContext("myEventBeanTest-context.xml"};
>  }
> 
>  @Override
>  protected RouteBuilder createRouteBuilder() throws Exception{
>     return new RouteBuilder(){
>          @Override
>          public void configure() throws Exception{
> 
> from("direct:start").beanRef("myEventBean","fromXML").beanRef("myEventBean","toJdbc").to("stream:out");
>          }
> 
>  @Test
>  public void secondTest() throws Exception{
>       Thread.sleep(3000);
>       template.sendBody("file://src/test/resources/inbox/?noop=true"); 
> <------????
>  }
> 
> ------------------------
> 
> fyi, I am injecting the route because I want to use the same context
> file/content that my live application has.
> 
> I'm sure this is based upon some fundamental misunderstanding, but I'm
> stuck.  I think I can see that I need to read the xml file into body.  I've
> trying moving the file endpoint up into the route, but then am not sure how
> to kick the whole thing off.
> 
> Which leads me to my questions (whew):
> 
> 
> 1) What magic do i need to work to feed the XML file?
> 
> 2) My noop option on the File component isn't working - the file gets
> deleted each time I run the test - anybody know why?
> 
> 3) I have read the api/javadocs on sendBody, sendBodyAndHeader, etc, but I'm
> having a hard time finding good explanations of what they do and how to use
> them (I have Camel in Action, which has been a big help except for this). 
> Can someone point me to a more thorough explanation/tutorial of using the
> producer template?...better than
> http://camel.apache.org/producertemplate.html  :)
> 
> 
> Thanks for any insight!
> -J
> 
> --
> View this message in context: http://camel.465427.n5.nabble.com/noob-spring-testing-question-tp4668163p4668163.html
> Sent from the Camel - Users mailing list archive at Nabble.com.

Re: noob spring testing question

Posted by dunnlow <du...@yahoo.com>.
Christian,

Thank you!  That was exactly what I was missing.  As you suggested, I pass
the body into the route via InputStream and Camel is smart enough to do the
rest.  Also, point taken about calling the methods directly for narrower
unit tests - plan to do that as well.  

Thanks again.
-J

--
View this message in context: http://camel.465427.n5.nabble.com/noob-spring-testing-question-tp4668163p4669586.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: noob spring testing question

Posted by Christian Schneider <ch...@die-schneider.net>.
Hi Dunnlow,

I would split the route for production into two routes. One from file to 
direct and one from direct to the beans and the rest.
So you can feed the xml into the direct route using the production 
config. You will not test the file endpoint config this way but the rest 
should work fine.

A nice thing you can do to feed files to the route is like this:

is = new FileInputStream("path");
producer.sendBody(is);

The camel type converters will read the file and send it to your beans.

One other thing for testing is to not forget to also do real unit tests. 
If your fromXML method looks like this:
MyEvent fromXml(Document doc);

Then simply create the converter class with new and feed fixed xml from 
a string into it. So you can test your own code without all the camel 
magic. These tests then also run much faster. The camel esting should 
only be the second round when the unit tests work fine.

Christian


Am 05.08.2011 01:43, schrieb dunnlow:
> I'm new to Camel (and relatively new to Spring).  I've got a route with a
> bean up and running but I want to perform some unit testing.  I'm trying to
> figure out how to "feed" my test with XML that is contained in a file.
>
> My working app has a bean with a method to load XML into the header
> parameters and a method to create SQL from the header parameters:
>
> This route works for me in my application:
> <camel:route>
>     <camel:from uri="file:/archive/inbox/>
>     <camel:bean ref="myEventBean" method="fromXML"/>
>     <camel:bean ref="myEventBean" method="toJdbc"/>
>     <camel:to uri="jdbc:dataSource"/>
> </camel:route>
>

-- 
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com