首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Apache Camel中对生产路线进行单元测试?

如何在Apache Camel中对生产路线进行单元测试?
EN

Stack Overflow用户
提问于 2011-04-14 21:55:26
回答 4查看 20.6K关注 0票数 23

假设我在单独的RouteBuilder类中创建了我的路由。看起来是这样的:

  • 从JMS队列中抓取消息
  • 执行一些转换、验证等
  • 根据验证结果转发到特定的JMS队列并将某些内容保存在DB

我想在没有JMS代理和DB的情况下对此路由进行单元测试。我知道我可以模拟我的处理器实现,但这还不够。我不想更改这个路由(假设我在jar文件中获得了这个类)。据我所知,Camel in Action (秒6.2.6),为了能够使用端点的模拟和其他东西,我需要更改我的路由端点定义(在本书的示例中,这是将"mina:tcp://miranda“更改为"mock:miranda”等)。

是否可以在不更改路由定义的情况下在完全隔离的情况下测试流?如果我将我的RouteBuilder作为一个单独的类,我是否被迫以某种方式“复制”路由定义并手动更改它?它不是在测试错误的东西吗?

我是Camel的新手,对我来说,能够在开发路由的同时进行独立的单元测试真的很酷。只是为了能够改变一些东西,运行小测试,观察结果等等。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-04-14 23:10:37

假设RouteBuilder类有硬编码的端点,那么它的测试就有点困难了。但是,如果将属性占位符用于端点uris的RouteBuilder是,那么您通常能够将一组不同的端点uris用于单元测试。正如《骆驼》一书第6章所解释的那样。

如果它们是硬编码的,那么您可以在单元测试中使用如下所示的带有特性的建议:https://camel.apache.org/components/latest/others/test-cdi.html#CDITesting-RoutesadvisingwithadviceWith

在Camel 2.7中,我们使得操纵路线变得更加容易,所以你可以删除部件,替换部件,等等。这就是link所说的编织内容。

例如,要模拟向数据库端点发送消息,可以使用上面的方法,并将to替换为另一个将消息发送到mock的位置。

在以前的版本中,您可以使用interceptSendToEndpoint技巧,该技巧也在Camel一书(第6.3.3节)中有所介绍

哦,您也可以用模拟组件替换组件,如第169页所示。现在从Camel2.8开始,mock组件将不再抱怨它不知道的uri参数。这意味着在每个组件级别上用mock替换组件要容易得多。

票数 25
EN

Stack Overflow用户

发布于 2011-04-14 23:15:46

我有过

代码语言:javascript
复制
   <bean id="properties" class="org.apache.camel.component.properties.PropertiesComponent">
        <property name="location" value="classpath:shop.properties"/>
    </bean>

    <route>
        <from uri="direct://stock"/>
        <to uri="{{stock.out}}"/>
    </route>

在我的spring文件中,然后在测试类路径上的shop.properties中,我有一个stock.out=xxxx,它在运行时被替换,因此我可以有不同的路由,一个用于运行时,另一个用于测试

在6.1.6的多环境单元测试中有一个更好的例子

票数 6
EN

Stack Overflow用户

发布于 2017-09-15 22:52:58

虽然您可以根据Claus Ibsen的回答使用截取和建议来交换端点,但我认为允许您的路由接受Endpoint实例要好得多,这样您的测试就不会耦合到生产端点URI。

例如,假设您有一个如下所示的RouteBuilder

代码语言:javascript
复制
public class MyRoute extends RouteBuilder {
    @Override
    public void configure() throws Exception {
        from("http://someapi/someresource")
        .process(exchange -> {
            // Do stuff with exchange
        })
        .to("activemq:somequeue");
    }
}

您可以像这样注入端点:

代码语言:javascript
复制
public class MyRoute extends RouteBuilder {
    private Endpoint in;
    private Endpoint out;

    // This is the constructor your production code can call
    public MyRoute(CamelContext context) {
        this.in = context.getEndpoint("http://someapi/someresource");
        this.out = context.getEndpoint("activemq:somequeue");
    }

    // This is the constructor your test can call, although it would be fine
    // to use in production too
    public MyRoute(Endpoint in, Endpoint out) {
        this.in = in;
        this.out = out;
    }

    @Override
    public void configure() throws Exception {
        from(this.in)
        .process(exchange -> {
            // Do stuff with exchange
        })
        .to(this.out);
    }
}

然后可以像这样进行测试:

代码语言:javascript
复制
public class MyRouteTest {
    private Endpoint in;
    private MockEndpoint out;
    private ProducerTemplate producer;

    @Before
    public void setup() {
        CamelContext context = new DefaultCamelContext();

        this.in = context.getEndpoint("direct:in");
        this.out = context.getEndpoint("mock:direct:out", MockEndpoint.class);
        this.producer = context.createProducerTemplate();
        this.producer.setDefaultEndpoint(this.in);

        RouteBuilder myRoute = new MyRoute(this.in, this.out);
        context.addRoutes(myRoute);

        context.start();
    }

    @Test
    public void test() throws Exception {
        this.producer.sendBody("Hello, world!");
        this.out.expectedMessageCount(1);
        this.out.assertIsSatisfied();
    }
} 

这有以下优点:

  • 您的测试非常简单易懂,甚至不需要扩展CamelTestSupport或其他帮助类
  • CamelContext是手动创建的,因此您可以确保只创建测试中的路由
  • 测试不关心生产路由URI
  • 如果您想要

,您仍然可以方便地将端点URI硬编码到路由类中

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5664331

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档