Using mock endpoints to verify routing logic

The ability to verify message flow using mock endpoints was built into the Camel framework from its inception. The Mock Component in the camel-core library provides you with a testing DSL that allows you to verify which messages have reached various named mock: endpoints defined in your route. This recipe will describe how to make use of this mock DSL.

Getting ready

To use this recipe you should first have a route test set up as described in the Testing routes defined in Java recipe.

The Java code for this recipe is located in the org.camelcookbook.examples.testing.mockreply package.

How to do it...

To use mock endpoints, perform the following steps:

  1. Within your route, use a mock: endpoint URI in any Camel DSL statement that produces a message to an endpoint, such as to(..) or wireTap(..):
    from("direct:start")
      .choice()
        .when().simple("${body} contains 'Camel'")
          .setHeader("verified").constant(true)
          .to("mock:camel")
        .otherwise()
          .to("mock:other")
      .end();
  2. Load the route into a Camel context, by overriding the CamelTestSupport class's createRouteBuilder() method, and start it as described in the Testing routes defined in Java recipe.
  3. Obtain a MockEndpoint from the Camel context that corresponds to the mock: endpoint URI you want to verify against.

    If you are extending CamelTestSupport, you can obtain the endpoint as follows:

    MockEndpoint mockCamel = getMockEndpoint("mock:camel");

    If you are working from first principles, do the following:

    MockEndpoint mockCamel = 
        camelContext.getEndpoint(
            "mock:camel", MockEndpoint.class);
  4. Use the MockEndpoint to define the number and content of the messages that you expect to reach the endpoint once you exercise the route:
    mockCamel.expectedMessageCount(1);
    mockCamel.message(0).body().isEqualTo("Camel Rocks");
    mockCamel.message(0).header("verified").isEqualTo(true);
  5. Send messages into the route through a ProducerTemplate:
    template.sendBody("direct:start", "Camel Rocks");
  6. Verify that the expectations that you set on the mocks were met:
    mockCamel.assertIsSatisfied();

Tip

This general pattern of setting expectations on an injected mock object (endpoint in this case), testing the code, and checking the results is known as an expect-run-verify cycle.

How it works...

A MockEndpoint is instantiated once when the Camel context is started, and collects all of the exchanges sent to it until the mock is destroyed. Any expectations defined on it are verified against that state.

Note

As MockEndpoint instances are stateful, it is essential that the Camel context be recreated between tests. If the Camel context is not recreated, then assertions against these mock endpoints may fail, as they still contain state from the previous test runs. For example, your number of messages expected assertion will fail as the mock will have gathered all of the messages from the last test run as well as the current run.

The methods on a MockEndpoint can broadly be categorized as expectations or assertions:

  • Expectations are defined before a mock is used (that is, before messages are sent to the route containing those mocks), and outline the expected state that the mock should accumulate by the end of the test.
  • Assertions are evaluated after the mock has been used, and are used to verify that the expectations have been met. They are also used to evaluate conditions against the total set of the mock's accumulated state.

Expectation method names begin with expect..(), and aside from the examples already shown, include methods such as the following:

expectedBodiesReceived(Object…)
expectedBodiesReceivedInAnyOrder(Object…)
expectedFileExists(String)
expectedMessageMatches(Predicate)
expectedMinimumMessageCount(int)

The message(int) statement allows you to define expectations on individual messages, including evaluating expressions on any part of the exchange, as well as answering timing questions:

mock.message(0).simple("${header[verified]} == true");
mock.message(0).arrives().noLaterThan(50).millis().beforeNext();

Assertions allow you to verify that the expectations were met, as well as assessing the entire set of messages sent to an endpoint during a test. These methods are prefixed by assert..(), and include the following:

assertIsSatisfied()
assertIsSatisfied(int timeoutForEmptyEndpoints)
assertIsNotSafisfied()
assertMessagesAscending(Expression)
assertMessagesDescending(Expression)
assertNoDuplicates(Expression)

Tip

There are many more assert and expect methods available to you other than those covered here. Take a look at the MockEndpoint JavaDocs for more information.

There's more...

A MockEndpoint instance grants you access to the set of exchanges it received during a test run. This is useful when you want to compare Exchange objects received by the endpoint, or verify the mechanical behavior of a route by inspecting the internal state of an individual exchange.

The following code tests whether a particular header is the same for two Exchange objects:

List<Exchange> receivedExchanges = mock.getReceivedExchanges();
Exchange exchange0 = receivedExchanges.get(0);
Exchange exchange1 = receivedExchanges.get(1);
// JUnit assertion
assertEquals(exchange0.getIn().getHeader("verified"),
             exchange1.getIn().getHeader("verified"));

This mechanism is useful for testing such things as exchange equality, or inspecting graphs of objects associated with the message.

Tip

You should only access received exchanges after calling endpoint.assertIsSatisfied().

You can also combine the fetching of an individual exchange with the assertion that it was received through use of the assertExchangeReceived(int) helper method. The preceding code could be rewritten as:

Exchange exchange0 = mock.assertExchangeReceived(0);
Exchange exchange1 = mock.assertExchangeReceived(1);
assertEquals(exchange0.getIn().getHeader("verified"),
             exchange1.getIn().getHeader("verified"));
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.51.228