camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > Mock
Date Fri, 04 Feb 2011 07:02:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2036/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/Mock">Mock</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~davsclaus">Claus
Ibsen</a>
    </h4>
        <br/>
                         <h4>Changes (3)</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" >Camel will by default wait 10 seconds
when the {{assertIsSatisfied()}} is invoked. This can be configured by setting the {{setResultWaitTime(millis)}}
method. <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">When
the assertion is satisfied then Camel will stop waiting and continue from the {{assertIsSatisfied}}
method. That means if a new message arrives on the mock endpoint, just a bit later, that arrival
will not affect the outcome of the assertion. Suppose you do want to test that no new messages
arrives after a period thereafter, then you can do that by setting the {{setAssertPeriod}}
method. <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h4. Using assertPeriod <br>*Available
as of Camel 2.7* <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>Then we create a new XML
file as follows, where we include the {{camel-route.xml}} file and define a spring bean with
the class {{org.apache.camel.impl.InterceptSendToMockEndpointStrategy}} which tells Camel
to mock all endpoints: <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">{snippet:id=e1|lang=xml|title=<span
class="diff-added-chars"style="background-color: #dfd;">test-</span>camel-route.xml|url=camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/mock/InterceptSendToMockEndpointStrategyTest.xml}</span>
<br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" >Then in your unit test you load
the new XML file <span class="diff-added-words"style="background-color: #dfd;">({{test-camel-route.xml}})</span>
instead of {{camel-route.xml}}. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>To only mock all [log]
endpoints you can define the pattern in the constructor for the bean: <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h2><a name="Mock-MockComponent"></a>Mock Component</h2>

<p><a href="/confluence/display/CAMEL/Testing" title="Testing">Testing</a>
of distributed and asynchronous processing is notoriously difficult. The <a href="/confluence/display/CAMEL/Mock"
title="Mock">Mock</a>, <a href="/confluence/display/CAMEL/Test" title="Test">Test</a>
and <a href="/confluence/display/CAMEL/DataSet" title="DataSet">DataSet</a> endpoints
work great with the <a href="/confluence/display/CAMEL/Testing" title="Testing">Camel
Testing Framework</a> to simplify your unit and integration testing using <a href="/confluence/display/CAMEL/Enterprise+Integration+Patterns"
title="Enterprise Integration Patterns">Enterprise Integration Patterns</a> and Camel's
large range of <a href="/confluence/display/CAMEL/Components" title="Components">Components</a>
together with the powerful <a href="/confluence/display/CAMEL/Bean+Integration" title="Bean
Integration">Bean Integration</a>.</p>

<p>The Mock component provides a powerful declarative testing mechanism, which is similar
to <a href="http://jmock.org" class="external-link" rel="nofollow">jMock</a> in
that it allows declarative expectations to be created on any Mock endpoint before a test begins.
Then the test is run, which typically fires messages to one or more endpoints, and finally
the expectations can be asserted in a test case to ensure the system  worked as expected.
</p>

<p>This allows you to test various things like:</p>
<ul>
	<li>The correct number of messages are received on each endpoint,</li>
	<li>The correct payloads are received, in the right order,</li>
	<li>Messages arrive on an endpoint in order, using some <a href="/confluence/display/CAMEL/Expression"
title="Expression">Expression</a> to create an order testing function,</li>
	<li>Messages arrive match some kind of <a href="/confluence/display/CAMEL/Predicate"
title="Predicate">Predicate</a> such as that specific headers have certain values,
or that parts of the messages match some predicate, such as by evaluating an <a href="/confluence/display/CAMEL/XPath"
title="XPath">XPath</a> or <a href="/confluence/display/CAMEL/XQuery" title="XQuery">XQuery</a>
<a href="/confluence/display/CAMEL/Expression" title="Expression">Expression</a>.</li>
</ul>


<p><b>Note</b> that there is also the <a href="/confluence/display/CAMEL/Test"
title="Test">Test endpoint</a> which is a Mock endpoint, but which uses a second
endpoint to provide the list of expected message bodies and automatically sets up the Mock
endpoint assertions. In other words, it's a Mock endpoint that automatically sets up its assertions
from some sample messages in a <a href="/confluence/display/CAMEL/File" title="File">File</a>
or <a href="/confluence/display/CAMEL/JPA" title="JPA">database</a>, for example.</p>

<h3><a name="Mock-URIformat"></a>URI format</h3>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
mock:someName[?options]
</pre>
</div></div>

<p>Where <b>someName</b> can be any string that uniquely identifies the
endpoint.</p>

<p>You can append query options to the URI in the following format, <tt>?option=value&amp;option=value&amp;...</tt></p>

<h3><a name="Mock-Options"></a>Options</h3>
<div class="confluenceTableSmall"><div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Option </th>
<th class='confluenceTh'> Default </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> <tt>reportGroup</tt> </td>
<td class='confluenceTd'> <tt>null</tt> </td>
<td class='confluenceTd'> A size to use a <a href="/confluence/display/CAMEL/Log"
title="Log">throughput logger</a> for reporting </td>
</tr>
</tbody></table>
</div>
</div>

<h3><a name="Mock-SimpleExample"></a>Simple Example</h3>

<p>Here's a simple example of Mock endpoint in use. First, the endpoint is resolved
on the context. Then we set an expectation, and then, after the test has run, we assert that
our expectations have been met.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
MockEndpoint resultEndpoint = context.resolveEndpoint(<span class="code-quote">"mock:foo"</span>,
MockEndpoint.class);

resultEndpoint.expectedMessageCount(2);

<span class="code-comment">// send some messages
</span>...

<span class="code-comment">// now lets <span class="code-keyword">assert</span>
that the mock:foo endpoint received 2 messages
</span>resultEndpoint.assertIsSatisfied();
</pre>
</div></div>

<p>You typically always call the <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/component/mock/MockEndpoint.html#assertIsSatisfied()"
class="external-link" rel="nofollow">assertIsSatisfied() method</a> to test that
the expectations were met after running a test.</p>

<p>Camel will by default wait 10 seconds when the <tt>assertIsSatisfied()</tt>
is invoked. This can be configured by setting the <tt>setResultWaitTime(millis)</tt>
method.</p>

<p>When the assertion is satisfied then Camel will stop waiting and continue from the
<tt>assertIsSatisfied</tt> method. That means if a new message arrives on the
mock endpoint, just a bit later, that arrival will not affect the outcome of the assertion.
Suppose you do want to test that no new messages arrives after a period thereafter, then you
can do that by setting the <tt>setAssertPeriod</tt> method.</p>

<h4><a name="Mock-UsingassertPeriod"></a>Using assertPeriod</h4>
<p><b>Available as of Camel 2.7</b><br/>
When the assertion is satisfied then Camel will stop waiting and continue from the <tt>assertIsSatisfied</tt>
method. That means if a new message arrives on the mock endpoint, just a bit later, that arrival
will not affect the outcome of the assertion. Suppose you do want to test that no new messages
arrives after a period thereafter, then you can do that by setting the <tt>setAssertPeriod</tt>
method, for example:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
MockEndpoint resultEndpoint = context.resolveEndpoint(<span class="code-quote">"mock:foo"</span>,
MockEndpoint.class);
resultEndpoint.setAssertPeriod(5000);
resultEndpoint.expectedMessageCount(2);

<span class="code-comment">// send some messages
</span>...

<span class="code-comment">// now lets <span class="code-keyword">assert</span>
that the mock:foo endpoint received 2 messages
</span>resultEndpoint.assertIsSatisfied();
</pre>
</div></div>

<h3><a name="Mock-Settingexpectations"></a>Setting expectations</h3>

<p>You can see from the javadoc of <a href="httphttp://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/component/mock/MockEndpoint.html"
class="external-link" rel="nofollow">MockEndpoint</a> the various helper methods
you can use to set expectations. The main methods are as follows: </p>
<div class="confluenceTableSmall"><div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Method </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/component/mock/MockEndpoint.html#expectedMessageCount(int)"
class="external-link" rel="nofollow">expectedMessageCount(int)</a> </td>
<td class='confluenceTd'> To define the expected message count on the endpoint. </td>
</tr>
<tr>
<td class='confluenceTd'> <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/component/mock/MockEndpoint.html#expectedMinimumMessageCount(int)"
class="external-link" rel="nofollow">expectedMinimumMessageCount(int)</a> </td>
<td class='confluenceTd'> To define the minimum number of expected messages on the endpoint.
</td>
</tr>
<tr>
<td class='confluenceTd'> <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/component/mock/MockEndpoint.html#expectedBodiesReceived(java.lang.Object...)"
class="external-link" rel="nofollow">expectedBodiesReceived(...)</a> </td>
<td class='confluenceTd'> To define the expected bodies that should be received (in
order). </td>
</tr>
<tr>
<td class='confluenceTd'> <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/component/mock/MockEndpoint.html#expectedHeaderReceived(java.lang.String,%20java.lang.String)"
class="external-link" rel="nofollow">expectedHeaderReceived(...)</a> </td>
<td class='confluenceTd'> To define the expected header that should be received </td>
</tr>
<tr>
<td class='confluenceTd'> <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/component/mock/MockEndpoint.html#expectsAscending(org.apache.camel.Expression)"
class="external-link" rel="nofollow">expectsAscending(Expression)</a> </td>
<td class='confluenceTd'> To add an expectation that messages are received in order,
using the given <a href="/confluence/display/CAMEL/Expression" title="Expression">Expression</a>
to compare messages. </td>
</tr>
<tr>
<td class='confluenceTd'> <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/component/mock/MockEndpoint.html#expectsDescending(org.apache.camel.Expression)"
class="external-link" rel="nofollow">expectsDescending(Expression)</a> </td>
<td class='confluenceTd'> To add an expectation that messages are received in order,
using the given <a href="/confluence/display/CAMEL/Expression" title="Expression">Expression</a>
to compare messages. </td>
</tr>
<tr>
<td class='confluenceTd'> <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/component/mock/MockEndpoint.html#expectsNoDuplicates(org.apache.camel.Expression)"
class="external-link" rel="nofollow">expectsNoDuplicates(Expression)</a> </td>
<td class='confluenceTd'> To add an expectation that no duplicate messages are received;
using an <a href="/confluence/display/CAMEL/Expression" title="Expression">Expression</a>
to calculate a unique identifier for each message. This could be something like the <tt>JMSMessageID</tt>
if using JMS, or some unique reference number within the message. </td>
</tr>
</tbody></table>
</div>
</div>

<p>Here's another example:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
resultEndpoint.expectedBodiesReceived(<span class="code-quote">"firstMessageBody"</span>,
<span class="code-quote">"secondMessageBody"</span>, <span class="code-quote">"thirdMessageBody"</span>);
</pre>
</div></div>

<h4><a name="Mock-Addingexpectationstospecificmessages"></a>Adding expectations
to specific messages</h4>

<p>In addition, you can use the <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/component/mock/MockEndpoint.html#message(int)"
class="external-link" rel="nofollow">message(int messageIndex)</a> method to add
assertions about a specific message that is received.</p>

<p>For example, to add expectations of the headers or body of the first message (using
zero-based indexing like <tt>java.util.List</tt>), you can use the following code:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
resultEndpoint.message(0).header(<span class="code-quote">"foo"</span>).isEqualTo(<span
class="code-quote">"bar"</span>);
</pre>
</div></div>

<p>There are some examples of the Mock endpoint in use in the <a href="http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/"
class="external-link" rel="nofollow">camel-core processor tests</a>.</p>


<h3><a name="Mock-Mockingexistingendpoints"></a>Mocking existing endpoints</h3>
<p><b>Available as of Camel 2.7</b></p>

<p>Camel now allows you to automatic mock existing endpoints in your Camel routes. Suppose
you have the given route below:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>Route</b></div><div class="codeContent
panelContent">
<pre class="code-java">@Override
<span class="code-keyword">protected</span> RouteBuilder createRouteBuilder()
<span class="code-keyword">throws</span> Exception {
    <span class="code-keyword">return</span> <span class="code-keyword">new</span>
RouteBuilder() {
        @Override
        <span class="code-keyword">public</span> void configure() <span class="code-keyword">throws</span>
Exception {
            from(<span class="code-quote">"direct:start"</span>).to(<span class="code-quote">"direct:foo"</span>).to(<span
class="code-quote">"log:foo"</span>).to(<span class="code-quote">"mock:result"</span>);

            from(<span class="code-quote">"direct:foo"</span>).transform(constant(<span
class="code-quote">"Bye World"</span>));
        }
    };
}
</pre>
</div></div>

<p>You can then use the <tt>adviceWith</tt> feature in Camel to mock all
the endpoints in a given route from your unit test, as shown below:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>adviceWith mocking all endpoints</b></div><div
class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">public</span> void testAdvisedMockEndpoints()
<span class="code-keyword">throws</span> Exception {
    <span class="code-comment">// advice the first route using the inlined AdviceWith
route builder
</span>    <span class="code-comment">// which has extended capabilities than
the regular route builder
</span>    context.getRouteDefinitions().get(0).adviceWith(context, <span class="code-keyword">new</span>
AdviceWithRouteBuilder() {
        @Override
        <span class="code-keyword">public</span> void configure() <span class="code-keyword">throws</span>
Exception {
            <span class="code-comment">// mock all endpoints
</span>            mockEndpoints();
        }
    });

    getMockEndpoint(<span class="code-quote">"mock:direct:start"</span>).expectedBodiesReceived(<span
class="code-quote">"Hello World"</span>);
    getMockEndpoint(<span class="code-quote">"mock:direct:foo"</span>).expectedBodiesReceived(<span
class="code-quote">"Hello World"</span>);
    getMockEndpoint(<span class="code-quote">"mock:log:foo"</span>).expectedBodiesReceived(<span
class="code-quote">"Bye World"</span>);
    getMockEndpoint(<span class="code-quote">"mock:result"</span>).expectedBodiesReceived(<span
class="code-quote">"Bye World"</span>);

    template.sendBody(<span class="code-quote">"direct:start"</span>, <span
class="code-quote">"Hello World"</span>);

    assertMockEndpointsSatisfied();

    <span class="code-comment">// additional test to ensure correct endpoints in registry
</span>    assertNotNull(context.hasEndpoint(<span class="code-quote">"direct:start"</span>));
    assertNotNull(context.hasEndpoint(<span class="code-quote">"direct:foo"</span>));
    assertNotNull(context.hasEndpoint(<span class="code-quote">"log:foo"</span>));
    assertNotNull(context.hasEndpoint(<span class="code-quote">"mock:result"</span>));
    <span class="code-comment">// all the endpoints was mocked
</span>    assertNotNull(context.hasEndpoint(<span class="code-quote">"mock:direct:start"</span>));
    assertNotNull(context.hasEndpoint(<span class="code-quote">"mock:direct:foo"</span>));
    assertNotNull(context.hasEndpoint(<span class="code-quote">"mock:log:foo"</span>));
}
</pre>
</div></div>

<p>Notice that the mock endpoints is given the uri <tt>mock:&lt;endpoint&gt;</tt>,
for example <tt>mock:direct:foo</tt>. Camel logs at <tt>INFO</tt>
level the endpoints being mocked:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
INFO  Adviced endpoint [direct:<span class="code-comment">//foo] with mock endpoint
[mock:direct:foo]</span>
</pre>
</div></div>

<p>Its also possible to only mock certain endpoints using a pattern. For example to
mock all <tt>log</tt> endpoints you do as shown:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>adviceWith mocking only log endpoints using
a pattern</b></div><div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">public</span> void testAdvisedMockEndpointsWithPattern()
<span class="code-keyword">throws</span> Exception {
    <span class="code-comment">// advice the first route using the inlined AdviceWith
route builder
</span>    <span class="code-comment">// which has extended capabilities than
the regular route builder
</span>    context.getRouteDefinitions().get(0).adviceWith(context, <span class="code-keyword">new</span>
AdviceWithRouteBuilder() {
        @Override
        <span class="code-keyword">public</span> void configure() <span class="code-keyword">throws</span>
Exception {
            <span class="code-comment">// mock only log endpoints
</span>            mockEndpoints(<span class="code-quote">"log*"</span>);
        }
    });

    <span class="code-comment">// now we can refer to log:foo as a mock and set our
expectations
</span>    getMockEndpoint(<span class="code-quote">"mock:log:foo"</span>).expectedBodiesReceived(<span
class="code-quote">"Bye World"</span>);

    getMockEndpoint(<span class="code-quote">"mock:result"</span>).expectedBodiesReceived(<span
class="code-quote">"Bye World"</span>);

    template.sendBody(<span class="code-quote">"direct:start"</span>, <span
class="code-quote">"Hello World"</span>);

    assertMockEndpointsSatisfied();

    <span class="code-comment">// additional test to ensure correct endpoints in registry
</span>    assertNotNull(context.hasEndpoint(<span class="code-quote">"direct:start"</span>));
    assertNotNull(context.hasEndpoint(<span class="code-quote">"direct:foo"</span>));
    assertNotNull(context.hasEndpoint(<span class="code-quote">"log:foo"</span>));
    assertNotNull(context.hasEndpoint(<span class="code-quote">"mock:result"</span>));
    <span class="code-comment">// only the log:foo endpoint was mocked
</span>    assertNotNull(context.hasEndpoint(<span class="code-quote">"mock:log:foo"</span>));
    assertNull(context.hasEndpoint(<span class="code-quote">"mock:direct:start"</span>));
    assertNull(context.hasEndpoint(<span class="code-quote">"mock:direct:foo"</span>));
}
</pre>
</div></div>

<p>The pattern supported can be a wildcard or a regular expression. See more details
about this at <a href="/confluence/display/CAMEL/Intercept" title="Intercept">Intercept</a>
as its the same matching function used by Camel. </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>Mind that mocking
endpoints causes the messages to be copied when they arrive on the mock.<br/>
That means Camel will use more memory. This may not be suitable when you send in a lot of
messages.</td></tr></table></div>

<h4><a name="Mock-Mockingexistingendpointsusingthe%7B%7Bcameltest%7D%7Dcomponent"></a>Mocking
existing endpoints using the <tt>camel-test</tt> component</h4>

<p>Instead of using the <tt>adviceWith</tt> to instruct Camel to mock endpoints,
you can easily enable this behavior when using the <tt>camel-test</tt> Test Kit.<br/>
The same route can be tested as follows. Notice that we return <tt>"*"</tt> from
the <tt>isMockEndpoints</tt> method, which tells Camel to mock all endpoints.<br/>
If you only want to mock all <tt>log</tt> endpoints you can return <tt>"log*"</tt>
instead. </p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>isMockEndpoints using camel-test kit</b></div><div
class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">public</span> class IsMockEndpointsJUnit4Test
<span class="code-keyword">extends</span> CamelTestSupport {

    @Override
    <span class="code-keyword">public</span> <span class="code-object">String</span>
isMockEndpoints() {
        <span class="code-comment">// override <span class="code-keyword">this</span>
method and <span class="code-keyword">return</span> the pattern <span class="code-keyword">for</span>
which endpoints to mock.
</span>        <span class="code-comment">// use * to indicate all
</span>        <span class="code-keyword">return</span> <span class="code-quote">"*"</span>;
    }

    @Test
    <span class="code-keyword">public</span> void testMockAllEndpoints() <span
class="code-keyword">throws</span> Exception {
        <span class="code-comment">// notice we have automatic mocked all endpoints
and the name of the endpoints is <span class="code-quote">"mock:uri"</span>
</span>        getMockEndpoint(<span class="code-quote">"mock:direct:start"</span>).expectedBodiesReceived(<span
class="code-quote">"Hello World"</span>);
        getMockEndpoint(<span class="code-quote">"mock:direct:foo"</span>).expectedBodiesReceived(<span
class="code-quote">"Hello World"</span>);
        getMockEndpoint(<span class="code-quote">"mock:log:foo"</span>).expectedBodiesReceived(<span
class="code-quote">"Bye World"</span>);
        getMockEndpoint(<span class="code-quote">"mock:result"</span>).expectedBodiesReceived(<span
class="code-quote">"Bye World"</span>);

        template.sendBody(<span class="code-quote">"direct:start"</span>, <span
class="code-quote">"Hello World"</span>);

        assertMockEndpointsSatisfied();

        <span class="code-comment">// additional test to ensure correct endpoints in
registry
</span>        assertNotNull(context.hasEndpoint(<span class="code-quote">"direct:start"</span>));
        assertNotNull(context.hasEndpoint(<span class="code-quote">"direct:foo"</span>));
        assertNotNull(context.hasEndpoint(<span class="code-quote">"log:foo"</span>));
        assertNotNull(context.hasEndpoint(<span class="code-quote">"mock:result"</span>));
        <span class="code-comment">// all the endpoints was mocked
</span>        assertNotNull(context.hasEndpoint(<span class="code-quote">"mock:direct:start"</span>));
        assertNotNull(context.hasEndpoint(<span class="code-quote">"mock:direct:foo"</span>));
        assertNotNull(context.hasEndpoint(<span class="code-quote">"mock:log:foo"</span>));
    }

    @Override
    <span class="code-keyword">protected</span> RouteBuilder createRouteBuilder()
<span class="code-keyword">throws</span> Exception {
        <span class="code-keyword">return</span> <span class="code-keyword">new</span>
RouteBuilder() {
            @Override
            <span class="code-keyword">public</span> void configure() <span
class="code-keyword">throws</span> Exception {
                from(<span class="code-quote">"direct:start"</span>).to(<span
class="code-quote">"direct:foo"</span>).to(<span class="code-quote">"log:foo"</span>).to(<span
class="code-quote">"mock:result"</span>);

                from(<span class="code-quote">"direct:foo"</span>).transform(constant(<span
class="code-quote">"Bye World"</span>));
            }
        };
    }
}
</pre>
</div></div>

<h4><a name="Mock-MockingexistingendpointswithXMLDSL"></a>Mocking existing
endpoints with XML DSL</h4>

<p>If you do not use the <tt>camel-test</tt> component for unit testing
(as shown above) you can use a different approach when using XML files for routes.<br/>
The solution is to create a new XML file used by the unit test and then include the intended
XML file which has the route you want to test.</p>

<p>Suppose we have the route in the <tt>camel-route.xml</tt> file:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>camel-route.xml</b></div><div
class="codeContent panelContent">
<pre class="code-xml"><span class="code-tag"><span class="code-comment">&lt;!--
this camel route is in the camel-route.xml file --&gt;</span></span>
<span class="code-tag">&lt;camelContext xmlns=<span class="code-quote">"http://camel.apache.org/schema/spring"</span>&gt;</span>

    <span class="code-tag">&lt;route&gt;</span>
        <span class="code-tag">&lt;from uri=<span class="code-quote">"direct:start"</span>/&gt;</span>
        <span class="code-tag">&lt;to uri=<span class="code-quote">"direct:foo"</span>/&gt;</span>
        <span class="code-tag">&lt;to uri=<span class="code-quote">"log:foo"</span>/&gt;</span>
        <span class="code-tag">&lt;to uri=<span class="code-quote">"mock:result"</span>/&gt;</span>
    <span class="code-tag">&lt;/route&gt;</span>

    <span class="code-tag">&lt;route&gt;</span>
        <span class="code-tag">&lt;from uri=<span class="code-quote">"direct:foo"</span>/&gt;</span>
        <span class="code-tag">&lt;transform&gt;</span>
            <span class="code-tag">&lt;constant&gt;</span>Bye World<span
class="code-tag">&lt;/constant&gt;</span>
        <span class="code-tag">&lt;/transform&gt;</span>
    <span class="code-tag">&lt;/route&gt;</span>

<span class="code-tag">&lt;/camelContext&gt;</span>
</pre>
</div></div>

<p>Then we create a new XML file as follows, where we include the <tt>camel-route.xml</tt>
file and define a spring bean with the class <tt>org.apache.camel.impl.InterceptSendToMockEndpointStrategy</tt>
which tells Camel to mock all endpoints:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>test-camel-route.xml</b></div><div
class="codeContent panelContent">
<pre class="code-xml"><span class="code-tag"><span class="code-comment">&lt;!--
the Camel route is defined in another XML file --&gt;</span></span>
<span class="code-tag">&lt;import resource=<span class="code-quote">"camel-route.xml"</span>/&gt;</span>

<span class="code-tag"><span class="code-comment">&lt;!-- bean which enables
mocking all endpoints --&gt;</span></span>
<span class="code-tag">&lt;bean id=<span class="code-quote">"mockAllEndpoints"</span>
class=<span class="code-quote">"org.apache.camel.impl.InterceptSendToMockEndpointStrategy"</span>/&gt;</span>
</pre>
</div></div>

<p>Then in your unit test you load the new XML file (<tt>test-camel-route.xml</tt>)
instead of <tt>camel-route.xml</tt>.</p>

<p>To only mock all <a href="/confluence/display/CAMEL/Log" title="Log">Log</a>
endpoints you can define the pattern in the constructor for the bean:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;bean id=<span class="code-quote">"mockAllEndpoints"</span>
class=<span class="code-quote">"org.apache.camel.impl.InterceptSendToMockEndpointStrategy"</span>&gt;</span>
    <span class="code-tag">&lt;constructor-arg index=<span class="code-quote">"0"</span>
value=<span class="code-quote">"log*"</span>/&gt;</span>
<span class="code-tag">&lt;/bean&gt;</span>
</pre>
</div></div>


<h3><a name="Mock-Testingwitharrivaltimes"></a>Testing with arrival times</h3>
<p><b>Available as of Camel 2.7</b></p>

<p>The <a href="/confluence/display/CAMEL/Mock" title="Mock">Mock</a> endpoint
stores the arrival time of the message as a property on the <a href="/confluence/display/CAMEL/Exchange"
title="Exchange">Exchange</a>.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
Date time = exchange.getProperty(Exchange.RECEIVED_TIMESTAMP, Date.class);
</pre>
</div></div>

<p>You can use this information to know when the message arrived on the mock. But it
also provides foundation to know the time interval between the previous and next message arrived
on the mock. You can use this to set expectations using the <tt>arrives</tt> DSL
on the <a href="/confluence/display/CAMEL/Mock" title="Mock">Mock</a> endpoint.</p>

<p>For example to say that the first message should arrive between 0-2 seconds before
the next you can do:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
mock.message(0).arrives().noLaterThan(2).seconds().beforeNext();
</pre>
</div></div>

<p>You can also define this as that 2nd message (0 index based) should arrive no later
than 0-2 seconds after the previous:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
mock.message(1).arrives().noLaterThan(2).seconds().afterPrevious();
</pre>
</div></div>

<p>You can also use between to set a lower bound. For example suppose that it should
be between 1-4 seconds:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
mock.message(1).arrives().between(1, 4).seconds().afterPrevious();
</pre>
</div></div>

<p>You can also set the expectation on all messages, for example to say that the gap
between them should be at most 1 second:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
mock.allMessages().arrives().noLaterThan(1).seconds().beforeNext();
</pre>
</div></div>

<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>time units</b><br
/>In the example above we use <tt>seconds</tt> as the time unit, but Camel
offers <tt>milliseconds</tt>, and <tt>minutes</tt> as well.</td></tr></table></div>


<h3><a name="Mock-SeeAlso"></a>See Also</h3>
<ul>
	<li><a href="/confluence/display/CAMEL/Configuring+Camel" title="Configuring Camel">Configuring
Camel</a></li>
	<li><a href="/confluence/display/CAMEL/Component" title="Component">Component</a></li>
	<li><a href="/confluence/display/CAMEL/Endpoint" title="Endpoint">Endpoint</a></li>
	<li><a href="/confluence/display/CAMEL/Getting+Started" title="Getting Started">Getting
Started</a></li>
</ul>

<ul>
	<li><a href="/confluence/display/CAMEL/Spring+Testing" title="Spring Testing">Spring
Testing</a></li>
	<li><a href="/confluence/display/CAMEL/Testing" title="Testing">Testing</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/Mock">View Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=52081&revisedVersion=41&originalVersion=40">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Mock?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message