-1

I have the following Spring route:

 <camelContext xmlns="http://camel.apache.org/schema/spring">
        <route>
            <from uri="activemq:topic:inbox" />
            <choice>
                <when>
                    <simple>${in.header.Value}</simple>
                    <log message="Cc: ${in.header.Value}" />
                </when>
            </choice>
            <to uri="mock:result" />
        </route>
 </camelContext>

I have the requirement to use Spring Testing (CamelSpringJUnit4ClassRunner), although I have found easy to understand examples on how to test the condition with Java DSL. My Test Class is like this:

@RunWith(CamelSpringJUnit4ClassRunner.class)
@BootstrapWith(CamelTestContextBootstrapper.class)
@ContextConfiguration(locations = "file:src/main/resources/META-INF/spring/camel-context-activemq-embedded.xml")
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
@MockEndpoints("log:*")
@DisableJmx(false)

public class MyTest{

    private Logger LOG = LogManager.getLogger(MyTest.class.getName());

    protected Exchange exchange;
    protected CustomComponent customComponent= new CustomComponent();

    @Produce(uri = "activemq:topic:inbox")
    protected ProducerTemplate template;

    @EndpointInject(uri = "mock:result")
    protected MockEndpoint resultEndpoint;

@Test
    public void tes1() throws InterruptedException {
        String headerValue= MyComponent.Value;
        EmailAddress recipients = new EmailAddress("recipient@example.com");
        template.sendBodyAndHeader("activemq:topic:inbox", recipients.toString(), headerValue);
        resultEndpoint.expectedBodiesReceived(headerValue);
        resultEndpoint.expectedHeaderReceived("header value", headerValue);
        resultEndpoint.expectedMessageCount(1);
    }

I am struggling to understand how to test the actual condition dictated by the CBR, but more importantly I am doubting whether this is even the right way to test it. MyComponent.VALUEConstant is a property specified in my custom component and the above test is actually passing. However, if I instantiated the headerValue with a different property on my component and therefore the condition is supposed to fail, the test passes. Can you please help?

Thank you,

I

panza
  • 1,341
  • 7
  • 38
  • 68

1 Answers1

1

Well, the first thing that I can see is that your simple expression lacks a comparison - it should probably be ${in.header.value} == 'wanted value'.

As far as testing is concerned - that really depends on the type of test. Here, you're doing integration testing so I'd verify that effects are as expected - DB changed the way it should etc. But since your route is only doing some logging then I'd change:

<log message="Cc: ${in.header.Value}" />

into

<log message="Cc: ${in.header.Value}" />
<to uri="mock:choice-triggered" />

and then verify that mock:choice-triggered endpoint received the message (or didn't, depending on the scenario). But in a test of a real-world route you'd probably want to verify that some data has been inserted into the DB or some message published to the MQ or that an email has been sent.

As far as your constant is concerned, I'd advise you to use externalized properties - both Camel and Spring have excellent support for property placeholders, I suggest you give them a try.

Miloš Milivojević
  • 5,219
  • 3
  • 26
  • 39
  • Hi, thank you for your help. I believe I was hugely confused by the simple expression itself as Value is an actual property in my custom component (only partially written by me) that only maps to "Value" . So, please correct me if I am wrong, I believe I need to create an instance of that value with an actual email address and then send it via sendBodyAndHeader, right? – panza Nov 14 '16 at 16:46
  • Yeah, I thought myself that I would need to have an endpoint (mock) to verify whether the message is received (inside ). However, I cannot change the Spring route. Is there any way (which is really what I was looking for) to inject another mock, but only in the test? – panza Nov 14 '16 at 16:52
  • Can I have more than one mock endpoint in my route? I have some simple log:message I want to verify as well as the choice condition. – panza Nov 14 '16 at 17:15
  • 1
    You can use property placeholders to externalize your `to` URIs and then override the properties in your test - that way your route logic does not change but you can use whatever URI you find useful. But generally, you'd want to avoid using mock endpoints in integration tests since their make your tests dissimilar to the expected runtime environment. – Miloš Milivojević Nov 14 '16 at 17:53
  • As for your first question - I don't really understand what you're trying to achieve with the constant. Also, if I'm not mistaken, the expression that you're using will evaluate to true if a header named 'Value' exists and is non-null, making it basically useless if wan't it to be true only for specific values. – Miloš Milivojević Nov 14 '16 at 17:56
  • Thank you for all the replies, much appreciated. The custom component declares a number of properties (one of them is the address) and creates the endpoint with them. My understanding is that the condition is used to check that that property is in the header. – panza Nov 15 '16 at 10:06
  • 1
    If you look at the [first sample of Simple language usage](https://camel.apache.org/simple#Simple-Samples) you'll see that the expression will only check that the header named `Value` exists but it will not check the value of the header, meaning that any value would be accepted as long as the header is there. – Miloš Milivojević Nov 15 '16 at 10:13
  • I have ultimately noticed that, no matter what I passed in the test was always passing. As long as the value is not null or empty. Thank you for this, I am questioning the value of my tests now. – panza Nov 15 '16 at 10:36