Reputation: 1675
I have an application build using Apache Camel 2.15.3. And I'm wiring the routes using spring-xml for dependency injection. I'm having a hard time understanding how to write automatic test for my routes. For example I might have the routes:
<onException id="Exception">
<exception>java.lang.Exception</exception>
<handled>
<constant>true</constant>
</handled>
<to uri="direct:fear"/>
</onException>
<route id="happyStory">
<from uri="direct:inTheBeginning"/>
<to uri="bean:enchantedKingdom?method=warn" />
<to uri="bean:fluffykins" />
</route>
<route id="scaryStory">
<from uri="direct:fear"/>
<onException>
<exception>java.lang.Exception</exception>
<handled>
<constant>true</constant>
</handled>
</onException>
<to uri="bean:monster"/>
<choice>
<when>
<simple>${header.succesfullywarned}</simple>
<to uri="bean:enchantedKingdom?method=hide"/>
</when>
<otherwise>
<to uri="bean:enchantedKingdom?method=panic" />
</otherwise>
</choice>
</route>
And I wan't to be able to say that when the bean method warn is called then the header "succesfullywarned" should be set in the message and then when the bean fluffykins is called there should be a exception that causes the message to get sent to "scaryStory" and in this case I wan't to assert that the bean method hide is called.
This is roughly my test class setup:
@RunWith(CamelSpringJUnit4ClassRunner.class)
@ContextConfiguration({"/META-INF/spring/route-
stories.xml","/META-INF/spring/beans.xml"})
@MockEndpointsAndSkip("(bean:fluffykins|bean:monster|bean:enchantedKingdom?method=warn|bean:enchantedKingdom?method=hide|bean:enchantedKingdom?method=panic)")
public class StoryHappyRouteTest extends CamelSpringTestSupport {
private String url = "direct:inTheBeginning";
@Autowired
private ApplicationContext applicationContext;
@Override
protected AbstractApplicationContext createApplicationContext() {
return (AbstractApplicationContext)applicationContext;
}
@Test
public void test(){
MockEndpoint warn = getMockEndpoint("mock:bean:enchantedKingdom?method=warn");
MockEndpoint fluffy = getMockEndpoint("mock:bean:fluffykins");
MockEndpoint monster = getMockEndpoint("mock:bean:monster");
MockEndpoint hide = getMockEndpoint("mock:bean:enchantedKingdom?method=hide");
MockEndpoint panic = getMockEndpoint("mock:bean:enchantedKingdom?method=panic");
fluffy.whenAnyExchangeReceived(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
System.out.println("Bunny!");
throw new NullPointerException();
}
});
template.sendBody(url,"");
warn.assertExchangeReceived(0);
fluffy.assertExchangeReceived(0);
monster.assertExchangeReceived(0);
panic.assertExchangeReceived(0);
}
}
I've read the chapter on testing in the first edition of Camel in action and look around in the manual (http://camel.apache.org/testing.html) but I don't understand how to apply it in my situation. In the above test everything works except where I have bean with multiple methods so I have an uri that contains "?method=methodname", and for some reason this makes it not work. I don't get an error or but the mock is not used and instead the actual beans are called. Is it not possible to do what I wan't to do? I can change the test setup in any way, but it is a given that the routes and the beans are defined in the spring-xml files.
I've taught about mocking the beans themselves and not the endpoints but the only way I can think of doing that is creating a "imposter-beans.xml" file where all the beans are defined, that points to stubbclasses that extend every class used in the routes. But that feels like an elaborate and wrong approach.
Upvotes: 0
Views: 904
Reputation: 55540
You can write code what to do when the mock receives a message. This is covered in the book in section 6.2.6, where you can use methods like whenAnyExchangeReceived
or whenExchangeReceived
, and in those inlined processors you can set the header, or throw an exception etc. See for example listing 6.9.
Upvotes: 1