使用MockEndpoints测试Camel

20

我有一系列经过“流水线化”处理的组件,它们都通过ActiveMQ消息队列进行通信。每个组件使用Camel将这些队列视为端点(Endpoint)。每个组件都使用相同的基本模式:

Basic component pattern

每个组件都会从输入队列中获取消息,处理这些消息,然后将1个或多个消息放置在输出队列上。 "输出"队列随后成为链中下一个组件的"输入"队列。非常基本。
我现在正在尝试卷起袖子,使用Camel的测试API提供的MockEndpoints为每个组件提供单元测试。我一直在查阅javadoc和Camel网站上的少数示例,但是很难将所有要点连接起来。
对于每个组件,我认为我的单元测试的一部分将想要完成以下三件事:
- 测试是否有消息等待在特定的"输入"队列上 - 获取这些消息并处理它们 - 将新消息推送到"输出"队列并验证它们是否已到达那里
我相信我需要创建每个队列的MockEndpoints,如下所示:
@EndpointInject(uri = "mock:inputQueue")
protected MockEndpoint intputQueue;

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

现在,在我的JUnit测试方法中,我可以设置预期并与这些端点进行交互:

@Test
public final void processMethodShouldSendToOutputQueue()
{
    Component comp = new Component();
    comp.process();

    outputQueue.assertIsSatisfied();
}

我只是不理解如何正确地连接所有内容:

  • 我该如何将comp连接到inputQueueoutputQueue MockEndpoints?
  • 对于每个MockEndpoint,我该如何设置期望,以便assertIsSatisfied()检查特定队列中是否存在消息,或者特定队列是否包含消息?

https://dev59.com/_2035IYBdhLWcg3wBLXb - Ben ODay
1个回答

12

Adam,有几种方法可以实现这一点。

对于POJO组件,单独对其进行黑盒测试以便关注业务逻辑,与任何Camel上下文/路由分开测试。

如果您想要进行端到端的路由测试,请考虑使用以下方法之一来验证路由中的每个步骤是否满足要求:

  • 使用NotifyBuilder来构建Exchange验证表达式(有些复杂,需要认真理解)
  • 使用AdviceWith在运行路由之前动态更改路由(添加Log/Mock端点等)

我更喜欢使用AdviceWith,因为它非常灵活,并且利用了熟悉的MockEndpoints。有关此内容的完整示例,请查看此单元测试

简而言之,您将创建一个单元测试,向您的路由中注入MockEndpoints,然后像往常一样针对它们进行验证...

context.getRouteDefinition("myRouteId").adviceWith(context, new AdviceWithRouteBuilder() {
    @Override
    public void configure() throws Exception {
        // mock all endpoints
        mockEndpoints();
    }
});

getMockEndpoint("mock:direct:start").expectedBodiesReceived("Hello World");

template.sendBody("direct:start", "Hello World");

我感谢boday的回答 - 是的,我将会分别测试组件(以及它们的“process”方法)。然而,作为组件和它们的输入/输出队列之间某种“集成测试”的一部分,我确实希望自动验证消息沿着定义良好的路线移动。AdviceWith API似乎很有趣,我会去看看。但是它的存在似乎使MockEndpoint变得不必要了。您能否澄清何时适合使用每个选项?再次感谢! - IAmYourFaja
Adam,为了进行真正的端到端测试,请使用AdviceWith动态地将MockEndpoints注入到您现有的生产路由中。Mock非常强大,因为提供了统计/断言API,但不应直接添加到生产路由中。我会更新我的答案,并给出一个示例... - Ben ODay
@boday,请问你能否完成一下示例,展示如何将一个“Exchange”发送到路由中?我之所以这样问是因为我不清楚如何将一个“Exchange”发送到路由的“from”。提前致谢。 - danidemi
当然,我更新了示例以包括template.sendBody()调用...请参考单元测试以获取完整示例... - Ben ODay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接