在Apache Camel应用程序中,单元测试如何注入模拟端点来代替真实端点?

Ste*_*ins 8 java spring eai apache-camel spring-boot

我正在使用Apache Camel 实现消息转换器模式,以使用来自RESTful端点的消息并将它们发送到AMQP端点.

封闭的应用程序基于Spring Boot,因此我使用Camel的" spring-boot "组件来集成这两个框架.正如这个spring-boot链接中的文档所示,我正在一个@Configuration注释类中实现我的Camel路由,该类扩展了RouteBuilder:

@Component
public class MyRestToAmqpRouter extends RouteBuilder {

   @Override
   public void configure() throws Exception {

      from("jetty:http://my-restful-url")
         .process(exchange -> {
            // convert the message body from JSON to XML, take some 
            // incoming header values and put them in the outgoing
            // body, etc...
         }).to("rabbitmq://my-rabbitmq-url");

   }

}
Run Code Online (Sandbox Code Playgroud)

我的问题涉及如何进行单元测试这种翻译,而不需要实际的RESTful端点或配置的RabbitMQ代理?我已经阅读了许多在线示例,以及Camel in Action一书......看起来单元测试Camel路线的典型方法是将路径切入粘贴到单元测试中,并替换一个或更多端点URL带有" mock:whatever".

我想这八九不离十的作品...但它非常脆弱,当有人不更新单元测试后改变了真正的代码测试套件将无法识别.

我试图使用模拟来修改一些基于Spring的单元测试示例,如下所示:

@RunWith(CamelSpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {Application.class})
public class MyRestToAmqpRouterTest extends AbstractJUnit4SpringContextTests {

    @Produce(uri = "jetty:http://my-restful-url")
    private ProducerTemplate fakeRest;

    @EndpointInject(uri = "rabbitmq://my-rabbit-url")
    private MockEndpoint fakeRabbit;

    @Test
    @DirtiesContext
    public void testRouter() throws InterruptedException {
        fakeRabbit.expectedMessageCount(1);
        fakeRest.sendBodyAndHeader("", "header-1", "some value");
        fakeRabbit.assertIsSatisfied();
    }

}
Run Code Online (Sandbox Code Playgroud)

我希望Camel会从单元测试中获取这些端点URL,将它们注册为模拟...然后在真实代码尝试使用这些URL时使用模拟而不是真实端点.

但是,我不确定这是可能的.当我在单元测试中使用真实的URL时,我得到了IllegalArgumentException,因为你显然无法将"真正的"端点URL注入MockEndpoint实例(只有前缀为" mock:"的URL ).

当我mock:...在单元测试中使用" "端点URL时,它没用,因为没有任何东西将它绑定到被测试类中的真实端点URL.这样就不会覆盖真正的端点URL.当执行实际代码时,它只是正常使用真实端点(目标是能够在没有外部依赖RabbitMQ的情况下进行测试).

我在这里错过了一些非常基本的东西吗?似乎有一种方法可以让单元测试将伪路由注入到这样的类中,这样被测试的代码就可以从真实端点切换到模拟端点,甚至没有意识到.或者,我想我可以重构我的代码,以便将匿名Processor提升为一个独立的类......然后我可以独立于路由单元测试其翻译逻辑.但这似乎是一个不完整的测试.

Cla*_*sen 5

一些提示你可以做什么。

你可以再读一遍Camel关于测试的书,注意使用advice

而且还有mockEndpointsAndSkip

您还可以使用该stub组件

或者在路由中使用属性占位符,然后将 uri 配置为模拟/存根等以进行测试,并使用真实的进行生产

  • 感谢 Claus 的详细回复(以及您在 Camel 上所做的总体工作!)。我最终能够组合出一个基于属性占位符的解决方案……尽管 Spring Boot 环境中的一些细节与老式基于 XML 的 Spring(甚至是基于注释的无 Boot 的 Spring)相比略有不同。我并不是在抱怨,而是由于 Spring Boot 正在成为 Pivotal 新 Spring 开发的主要推荐方法,因此很高兴在文档中看到更多以 Boot 为中心的示例以及旧的 Spring 示例。 (2认同)