如果你正在使用Spring(这通常是一个好主意),我想分享一下我的方法。
你的生产路由是一个带有特殊类MyRoute的Spring bean。
@Component
public class MyRoute extends RouteBuilder {
public static final String IN = "jms://inqueue";
@Override
public void configure() throws Exception {
from(IN)
.process(exchange -> {
// 处理exchange
})
.to("activemq:somequeue");
}
}
所以在测试中,你可以很容易地像这样覆盖它(这是一个spring java配置内部(对于测试类)的类):
static class TestConfig extends IntegrationTestConfig {
@Bean
public MyRoute myRoute(){
return new MyRoute() {
@Override
public void configure() throws Exception {
interceptFrom(MyRoute.IN)
.choice()
.when(x -> delayThisMessagePredicate.matches(x)) // 使predicate在测试之间可修改
.to("log:delayed")
.delay(5000)
.endChoice();
super.configure();
}
};
}
}
注意super.configure()会安装你的生产路由,你可以使用interceptFrom、interceptSendToEndpoint来注入测试代码,例如引发异常。
我还添加了一些辅助路由。通过这个路由,我可以测试一个文件是否在输出文件夹中生成,它可以是一个JMS消费者...
@Bean
public RouteBuilder createOutputRoute() {
return new RouteBuilder() {
@Override
public void configure() {
fromF(FILE_IN,
outputDir)
.to("mock:output")
.routeId("doneRoute");
};
}
对于JMS/JDBC/...,还有Mockrunner。通过在你的测试配置中使用下面的代码,你几乎可以完成:你的JMS连接工厂被一个模拟实现替换,所以现在你甚至可以将一些内容放入JMS并从JMS读取(使用简单的camel route,就像上面解释的那样)进行验证。不要忘记在模拟中创建一个队列。
@Bean(JMS_MOCK_CONNECTION_FACTORY)
@Primary
public ConnectionFactory jmsConnectionFactory() {
return (new JMSMockObjectFactory()).getMockQueueConnectionFactory();
}
我不喜欢AdviseWith,是的,它很灵活,但是在测试中需要手动处理camelContext,这对我来说太过于侵入性了。我不想在成百上千个测试中加入那段代码,也不想为此创建一个框架。而且,如果你使用两个库,这两个库都需要你继承某个类,并且你可能有自己的测试类层次结构,在其中看不到CamelTestSupport。我尽量避免在我的测试中有类层次结构,以保持测试的独立性。子类化意味着你需要发生一些魔法(你在测试中看不到那段代码)。如果你修改了那个魔法,你会影响很多测试。我在这方面使用spring java配置集。
adviceWith
更快,并且在我的测试类中更易读(您还可以重写方法:useOverridePropertiesWithPropertiesComponent()
)。 - рüффп