camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > Camel Test
Date Thu, 12 May 2011 08:29:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/9/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/CAMEL/Camel+Test">Camel
Test</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~davsclaus">Claus
Ibsen</a>
    </h4>
        <br/>
                         <h4>Changes (1)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{tip} <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">{warning:title=Beware}
<br>When using this the [CamelContext] will keep state between tests, so have that in
mind. So if your unit tests start to fail for no apparent reason, it could be due this fact.
So use this feature with a bit of care. <br>{warning} <br> <br></td></tr>
            <tr><td class="diff-unchanged" >You may want to do this once, to share
the [CamelContext] between test methods, to speedup unit testing. This requires to use JUnit
4! In your unit test method you have to extend the {{org.apache.camel.test.junit4.CamelTestSupport}}
or the {{org.apache.camel.test.junit4.CamelSpringTestSupport}} test class and override the
{{isCreateCamelContextPerClass}} method and return {{true}} as shown in the following example:
<br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h2><a name="CamelTest-CamelTest"></a>Camel Test</h2>

<p>As a simple alternative to using <a href="/confluence/display/CAMEL/Spring+Testing"
title="Spring Testing">Spring Testing</a> or <a href="/confluence/display/CAMEL/Guice"
title="Guice">Guice</a> the <b>camel-test</b> module was introduced into
the Camel 2.0 trunk so you can perform powerful <a href="/confluence/display/CAMEL/Testing"
title="Testing">Testing</a> of your <a href="/confluence/display/CAMEL/Enterprise+Integration+Patterns"
title="Enterprise Integration Patterns">Enterprise Integration Patterns</a> easily.</p>

<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/information.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td>The <tt>camel-test</tt>
JAR is using JUnit. There is an alternative <tt>camel-testng</tt> JAR (Camel 2.8
onwards) using the <a href="http://testng.org/doc/index.html" class="external-link" rel="nofollow">TestNG</a>
test framework.</td></tr></table></div>

<h3><a name="CamelTest-Addingtoyourpom.xml"></a>Adding to your pom.xml</h3>

<p>To get started using Camel Test you will need to add an entry to your pom.xml</p>

<h4><a name="CamelTest-JUnit"></a>JUnit</h4>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;dependency&gt;</span>
  <span class="code-tag">&lt;groupId&gt;</span>org.apache.camel<span
class="code-tag">&lt;/groupId&gt;</span>
  <span class="code-tag">&lt;artifactId&gt;</span>camel-test<span class="code-tag">&lt;/artifactId&gt;</span>
  <span class="code-tag">&lt;version&gt;</span>${camel-version}<span
class="code-tag">&lt;/version&gt;</span>
  <span class="code-tag">&lt;scope&gt;</span>test<span class="code-tag">&lt;/scope&gt;</span>
<span class="code-tag">&lt;/dependency&gt;</span>
</pre>
</div></div>

<h4><a name="CamelTest-TestNG"></a>TestNG</h4>
<p><b>Available as of Camel 2.8</b></p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;dependency&gt;</span>
  <span class="code-tag">&lt;groupId&gt;</span>org.apache.camel<span
class="code-tag">&lt;/groupId&gt;</span>
  <span class="code-tag">&lt;artifactId&gt;</span>camel-testng<span
class="code-tag">&lt;/artifactId&gt;</span>
  <span class="code-tag">&lt;version&gt;</span>${camel-version}<span
class="code-tag">&lt;/version&gt;</span>
  <span class="code-tag">&lt;scope&gt;</span>test<span class="code-tag">&lt;/scope&gt;</span>
<span class="code-tag">&lt;/dependency&gt;</span>
</pre>
</div></div>

<p>You might also want to add slf4j and log4j to ensure nice logging messages (and maybe
adding a <a href="http://svn.apache.org/repos/asf/camel/trunk/components/camel-test/src/test/resources/log4j.properties"
class="external-link" rel="nofollow">log4j.properties</a> file into your src/test/resources
directory).</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;dependency&gt;</span>
  <span class="code-tag">&lt;groupId&gt;</span>org.slf4j<span class="code-tag">&lt;/groupId&gt;</span>
  <span class="code-tag">&lt;artifactId&gt;</span>slf4j-log4j12<span
class="code-tag">&lt;/artifactId&gt;</span>
  <span class="code-tag">&lt;scope&gt;</span>test<span class="code-tag">&lt;/scope&gt;</span>
<span class="code-tag">&lt;/dependency&gt;</span>
<span class="code-tag">&lt;dependency&gt;</span>
  <span class="code-tag">&lt;groupId&gt;</span>log4j<span class="code-tag">&lt;/groupId&gt;</span>
  <span class="code-tag">&lt;artifactId&gt;</span>log4j<span class="code-tag">&lt;/artifactId&gt;</span>
  <span class="code-tag">&lt;scope&gt;</span>test<span class="code-tag">&lt;/scope&gt;</span>
<span class="code-tag">&lt;/dependency&gt;</span>
</pre>
</div></div>

<h3><a name="CamelTest-Writingyourtest"></a>Writing your test</h3>

<p>You firstly need to derive from the class <b>CamelTestSupport</b> and
typically you will need to override the <b>createRouteBuilder()</b> method to
create routes to be tested.</p>

<p>Here is an <a href="http://svn.apache.org/repos/asf/camel/trunk/components/camel-test/src/test/java/org/apache/camel/test/patterns/FilterTest.java"
class="external-link" rel="nofollow">example</a>. </p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">public</span> class FilterTest
<span class="code-keyword">extends</span> CamelTestSupport {

    @EndpointInject(uri = <span class="code-quote">"mock:result"</span>)
    <span class="code-keyword">protected</span> MockEndpoint resultEndpoint;

    @Produce(uri = <span class="code-quote">"direct:start"</span>)
    <span class="code-keyword">protected</span> ProducerTemplate template;

    <span class="code-keyword">public</span> void testSendMatchingMessage() <span
class="code-keyword">throws</span> Exception {
        <span class="code-object">String</span> expectedBody = <span class="code-quote">"&lt;matched/&gt;"</span>;

        resultEndpoint.expectedBodiesReceived(expectedBody);

        template.sendBodyAndHeader(expectedBody, <span class="code-quote">"foo"</span>,
<span class="code-quote">"bar"</span>);

        resultEndpoint.assertIsSatisfied();
    }

    <span class="code-keyword">public</span> void testSendNotMatchingMessage()
<span class="code-keyword">throws</span> Exception {
        resultEndpoint.expectedMessageCount(0);

        template.sendBodyAndHeader(<span class="code-quote">"&lt;notMatched/&gt;"</span>,
<span class="code-quote">"foo"</span>, <span class="code-quote">"notMatchedHeaderValue"</span>);

        resultEndpoint.assertIsSatisfied();
    }

    @Override
    <span class="code-keyword">protected</span> RouteBuilder createRouteBuilder()
{
        <span class="code-keyword">return</span> <span class="code-keyword">new</span>
RouteBuilder() {
            <span class="code-keyword">public</span> void configure() {
                from(<span class="code-quote">"direct:start"</span>).filter(header(<span
class="code-quote">"foo"</span>).isEqualTo(<span class="code-quote">"bar"</span>)).to(<span
class="code-quote">"mock:result"</span>);
            }
        };
    }
}
</pre>
</div></div>

<p>Notice how you can use the various <a href="/confluence/display/CAMEL/Bean+Integration"
title="Bean Integration">Camel binding and injection annotations</a> to inject individual
<a href="/confluence/display/CAMEL/Endpoint" title="Endpoint">Endpoint</a> objects
- particularly the <a href="/confluence/display/CAMEL/Mock" title="Mock">Mock endpoints</a>
which are very useful for <a href="/confluence/display/CAMEL/Testing" title="Testing">Testing</a>.
Also you can inject <a href="/confluence/display/CAMEL/POJO+Producing" title="POJO Producing">producer
objects such as ProducerTemplate or some application code interface</a> for sending
messages or invoking services.</p>


<h3><a name="CamelTest-JNDI"></a>JNDI</h3>

<p>Camel uses a <a href="/confluence/display/CAMEL/Registry" title="Registry">Registry</a>
to allow you to configure <a href="/confluence/display/CAMEL/Component" title="Component">Component</a>
or <a href="/confluence/display/CAMEL/Endpoint" title="Endpoint">Endpoint</a>
instances or <a href="/confluence/display/CAMEL/Bean+Integration" title="Bean Integration">Beans
used in your routes</a>. If you are not using <a href="/confluence/display/CAMEL/Spring"
title="Spring">Spring</a> or <a href="/confluence/pages/createpage.action?spaceKey=CAMEL&amp;title=OSGi&amp;linkCreation=true&amp;fromPageId=104074"
class="createlink">OSGi</a> then <a href="/confluence/display/CAMEL/JNDI" title="JNDI">JNDI</a>
is used as the default registry implementation.</p>

<p>So you will also need to create a <b>jndi.properties</b> file in your
<b>src/test/resources</b> directory so that there is a default registry available
to initialise the <a href="/confluence/display/CAMEL/CamelContext" title="CamelContext">CamelContext</a>.</p>

<p>Here is <a href="http://svn.apache.org/repos/asf/camel/trunk/components/camel-test/src/test/resources/jndi.properties"
class="external-link" rel="nofollow">an example jndi.properties file</a></p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
java.naming.factory.initial = org.apache.camel.util.jndi.CamelInitialContextFactory
</pre>
</div></div>

<h3><a name="CamelTest-Dynamicallyassigningports"></a>Dynamically assigning
ports</h3>
<p><b>Available as of Camel 2.7</b></p>

<p>Tests that use port numbers will fail if that port is already on use. <tt>AvailablePortFinder</tt>
provides methods for finding unused port numbers at runtime. </p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-comment">// Get the next available port number starting from the <span
class="code-keyword">default</span> starting port of 1024
</span><span class="code-object">int</span> port1 = AvailablePortFinder.getNextAvailable();
/* 
 * Get another port. Note that just getting a port number does not reserve it so
 * we look starting one past the last port number we got.
 */
<span class="code-object">int</span> port2 = AvailablePortFinder.getNextAvailable(port1
+ 1);
</pre>
</div></div>


<h3><a name="CamelTest-SetupCamelContextonceperclass%2Corpereverytestmethod"></a>Setup
CamelContext once per class, or per every test method</h3>
<p><b>Available as of Camel 2.8</b></p>

<p>The <a href="/confluence/display/CAMEL/Camel+Test" title="Camel Test">Camel
Test</a> kit will by default setup and shutdown <a href="/confluence/display/CAMEL/CamelContext"
title="CamelContext">CamelContext</a> per every test method in your test class. So
for example if you have 3 test methods, then <a href="/confluence/display/CAMEL/CamelContext"
title="CamelContext">CamelContext</a> is started and shutdown after each test, that
is 3 times.</p>

<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/check.gif" width="16" height="16"
align="absmiddle" alt="" border="0"></td><td><b>TestNG</b><br
/>This feature is also supported in camel-testng</td></tr></table></div>

<div class='panelMacro'><table class='warningMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/forbidden.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td><b>Beware</b><br
/>When using this the <a href="/confluence/display/CAMEL/CamelContext" title="CamelContext">CamelContext</a>
will keep state between tests, so have that in mind. So if your unit tests start to fail for
no apparent reason, it could be due this fact. So use this feature with a bit of care.</td></tr></table></div>

<p>You may want to do this once, to share the <a href="/confluence/display/CAMEL/CamelContext"
title="CamelContext">CamelContext</a> between test methods, to speedup unit testing.
This requires to use JUnit 4! In your unit test method you have to extend the <tt>org.apache.camel.test.junit4.CamelTestSupport</tt>
or the <tt>org.apache.camel.test.junit4.CamelSpringTestSupport</tt> test class
and override the <tt>isCreateCamelContextPerClass</tt> method and return <tt>true</tt>
as shown in the following example:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>Setup CamelContext once per class</b></div><div
class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">public</span> class FilterCreateCamelContextPerClassTest
<span class="code-keyword">extends</span> CamelTestSupport {

    @EndpointInject(uri = <span class="code-quote">"mock:result"</span>)
    <span class="code-keyword">protected</span> MockEndpoint resultEndpoint;

    @Produce(uri = <span class="code-quote">"direct:start"</span>)
    <span class="code-keyword">protected</span> ProducerTemplate template;

    @Override
    <span class="code-keyword">public</span> <span class="code-object">boolean</span>
isCreateCamelContextPerClass() {
        <span class="code-comment">// we override <span class="code-keyword">this</span>
method and <span class="code-keyword">return</span> <span class="code-keyword">true</span>,
to tell Camel test-kit that
</span>        <span class="code-comment">// it should only create CamelContext
once (per class), so we will
</span>        <span class="code-comment">// re-use the CamelContext between each
test method in <span class="code-keyword">this</span> class
</span>        <span class="code-keyword">return</span> <span class="code-keyword">true</span>;
    }

    @Test
    <span class="code-keyword">public</span> void testSendMatchingMessage() <span
class="code-keyword">throws</span> Exception {
        <span class="code-object">String</span> expectedBody = <span class="code-quote">"&lt;matched/&gt;"</span>;

        resultEndpoint.expectedBodiesReceived(expectedBody);

        template.sendBodyAndHeader(expectedBody, <span class="code-quote">"foo"</span>,
<span class="code-quote">"bar"</span>);

        resultEndpoint.assertIsSatisfied();
    }

    @Test
    <span class="code-keyword">public</span> void testSendNotMatchingMessage()
<span class="code-keyword">throws</span> Exception {
        resultEndpoint.expectedMessageCount(0);

        template.sendBodyAndHeader(<span class="code-quote">"&lt;notMatched/&gt;"</span>,
<span class="code-quote">"foo"</span>, <span class="code-quote">"notMatchedHeaderValue"</span>);

        resultEndpoint.assertIsSatisfied();
    }

    @Override
    <span class="code-keyword">protected</span> RouteBuilder createRouteBuilder()
{
        <span class="code-keyword">return</span> <span class="code-keyword">new</span>
RouteBuilder() {
            <span class="code-keyword">public</span> void configure() {
                from(<span class="code-quote">"direct:start"</span>).filter(header(<span
class="code-quote">"foo"</span>).isEqualTo(<span class="code-quote">"bar"</span>)).to(<span
class="code-quote">"mock:result"</span>);
            }
        };
    }
}
</pre>
</div></div>


<h3><a name="CamelTest-SeeAlso"></a>See Also</h3>

<ul>
	<li><a href="/confluence/display/CAMEL/Testing" title="Testing">Testing</a></li>
	<li><a href="/confluence/display/CAMEL/Mock" title="Mock">Mock</a></li>
	<li><a href="/confluence/display/CAMEL/Test" title="Test">Test</a></li>
</ul>

    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Camel+Test">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=104074&revisedVersion=14&originalVersion=13">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Camel+Test?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message