Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: updated link to jMock

Mock Component

Include Page
Testing Summary Include
Testing Summary Include

The Mock component provides a powerful declarative testing mechanism, which is similar to jMock 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.

...

Warning
titleMock endpoints keep received Exchanges in memory indefinitely

Remember that Mock is designed for testing. When you add Mock endpoints to a route, each Exchange sent to the endpoint will be stored (to allow for later validation) in memory until explicitly reset or the JVM is restarted. If you are sending high volume and/or large messages, this may cause excessive memory use. If your goal is to test deployable routes inline, consider using NotifyBuilder or AdviceWith in your tests instead of adding Mock endpoints to routes directly.

From Camel 2.10 onwards there are two new options retainFirst, and retainLast that can be used to limit the number of messages the Mock endpoints keep in memory.

URI format

Code Block

mock:someName[?options]

Where someName can be any string that uniquely identifies the endpoint.

...

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.

Code Block

MockEndpoint resultEndpoint = context.resolveEndpoint("mock:foo", MockEndpoint.class);

resultEndpoint.expectedMessageCount(2);

// send some messages
...

// now lets assert that the mock:foo endpoint received 2 messages
resultEndpoint.assertIsSatisfied();

...

Available as of Camel 2.7
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, for example:

Code Block

MockEndpoint resultEndpoint = context.resolveEndpoint("mock:foo", MockEndpoint.class);
resultEndpoint.setAssertPeriod(5000);
resultEndpoint.expectedMessageCount(2);

// send some messages
...

// now lets assert that the mock:foo endpoint received 2 messages
resultEndpoint.assertIsSatisfied();

...

Here's another example:

Code Block

resultEndpoint.expectedBodiesReceived("firstMessageBody", "secondMessageBody", "thirdMessageBody");

...

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

Code Block

resultEndpoint.message(0).header("foo").isEqualTo("bar");

...

Notice that the mock endpoints is given the uri mock:<endpoint>, for example mock:direct:foo. Camel logs at INFO level the endpoints being mocked:

Code Block

INFO  Adviced endpoint [direct://foo] with mock endpoint [mock:direct:foo]

...

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

To only mock all log Log endpoints you can define the pattern in the constructor for the bean:

Code Block
xml
xml

<bean id="mockAllEndpoints" class="org.apache.camel.impl.InterceptSendToMockEndpointStrategy">
    <constructor-arg index="0" value="log*"/>
</bean>

...

For example in the code below, we only want to retain a copy of the first 5 and last 5 Exchanges the mock receives.

Code Block

  MockEndpoint mock = getMockEndpoint("mock:data");
  mock.setRetainFirst(5);
  mock.setRetainLast(5);
  mock.expectedMessageCount(2000);

  ...

  mock.assertIsSatisfied();

...

The Mock endpoint stores the arrival time of the message as a property on the Exchange.

Code Block

Date time = exchange.getProperty(Exchange.RECEIVED_TIMESTAMP, Date.class);

...

For example to say that the first message should arrive between 0-2 seconds before the next you can do:

Code Block

mock.message(0).arrives().noLaterThan(2).seconds().beforeNext();

You can also define this as that 2nd message (0 index based) should arrive no later than 0-2 seconds after the previous:

Code Block

mock.message(1).arrives().noLaterThan(2).seconds().afterPrevious();

You can also use between to set a lower bound. For example suppose that it should be between 1-4 seconds:

Code Block

mock.message(1).arrives().between(1, 4).seconds().afterPrevious();

You can also set the expectation on all messages, for example to say that the gap between them should be at most 1 second:

Code Block

mock.allMessages().arrives().noLaterThan(1).seconds().beforeNext();
Tip
titletime units

In the example above we use seconds as the time unit, but Camel offers milliseconds, and minutes as well.

Include Page
Endpoint See Also
Endpoint See Also