如何在 Camel 测试中模拟 AMQP 消费者?

Dir*_*oys 4 java testing mocking apache-camel

假设我有以下路线:

from(rabbitMQUri)
    .to(myCustomerProcessor)
    .choice()
        .when(shouldGotoA)
            .to(fizz)
        .when(shouldGotoB)
            .to(buzz)
        .otherwise()
            .to(foo);
Run Code Online (Sandbox Code Playgroud)

让我们假设myCustomProcessor的曲调shouldGotoA,并shouldGotoB根据从RabbitMQ的消耗的消息。

我想对 3 个场景进行单元测试:

  1. 一条 " fizz " 消息被消耗并shouldGotoA设置为 true,它执行第一个when(...).
  2. 一条 " buzz " 消息被消耗并shouldGotoB设置为 true,它执行第二个when(...).
  3. 一条“ foo ”消息被消耗并被otherwise()执行。

我的问题是:如何模拟/存根 RabbitMQ 端点,以便路由在生产中正常执行,但我不必将测试实际连接到 RabbitMQ 服务器?我需要某种“模拟消息”生产者。

代码示例或片段将非常有帮助,非常感谢!

mat*_*ell 6

这是组合合适测试的一种方式。

首先定义一个空的 Camel Context,其中只有一个 ProducerTemplate:

<camel:camelContext id="camelContext">
   <camel:template id="producerTemplate" />
</camel:camelContext>
Run Code Online (Sandbox Code Playgroud)

我这样做是为了在执行测试时,我可以控制实际开始的路线,因为我不希望所有路线都在测试期间开始。

现在在测试类本身中,您将需要对生产者模板和 Camel Context 的引用。就我而言,我使用的是 Spring 并将它们自动连接到:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/spring/spring-test-camel.xml" })
public class MyTest {

    @Autowired
    private ProducerTemplate producerTemplate;

    @Autowired
    private CamelContext camelContext;
Run Code Online (Sandbox Code Playgroud)

在测试本身中,将上下文中的 RabbitMQ/ActiveMQ/JMS 组件替换为 seda 或直接组件。例如,用 seda 队列替换所有 JMS 调用。

camelContext.removeComponent("jms");
camelContext.addComponent("jms", this.camelContext.getComponent("seda"));
camelContext.addRoutes(this.documentBatchRouting);
Run Code Online (Sandbox Code Playgroud)

现在,无论何时读取或写入 JMS URI,它实际上都会进入 seda 队列。这类似于将新 URI 注入组件中,但需要较少的配置,并允许您向路由添加新端点,而不必担心记住注入所有 URI。

最后在测试中,使用生产者模板发送测试消息:

producerTemplate.sendBody("jms:MyQueue", 2);
Run Code Online (Sandbox Code Playgroud)

然后你的路线应该执行,你可以测试你的期望。

需要注意的两点是:

  1. 您的事务边界可能会发生变化,尤其是当您用直接组件替换 JMS 队列时

  2. 如果您正在测试多条路线,则必须小心地在该路线的测试结束时从 Camel Context 中删除该路线。

  • 什么是camelContext.addRoutes(this.documentBatchRouting);? (2认同)

Pet*_*der 5

这可能取决于您使用什么组件(AMQP 或 RabbitMQ)进行通信。

最重要的骆驼示例代码资源是JUnit测试案例的来源。

这两个文件与您需要的东西做类似的事情是这两个,但您可能想在测试用例中环顾四周以获得灵感: AMQPRouteTest.java RabbitMQConsumerIntTest.java

使路由可测试的一种更“基本”的方法是将“from” uri 设为参数。假设你让你的 RouteBuilder 是这样的:

   private String fromURI = "amqp:/..";

   public void setFromURI(String fromURI){
     this.fromURI = fromURI;
   }

   public void configure(){
     from(fromURI).whatever();
   }
Run Code Online (Sandbox Code Playgroud)

然后,您可以在开始单元测试之前在 fromURI 中注入“seda:foobar”端点。该SEDA终点是微不足道的测试。这假设您不需要测试 AMQP/RabbitMQ 特定的构造,而只需接收有效负载。