当前位置: 首页 > 知识库问答 >
问题:

Spring Boot Apache骆驼路线测试

酆高翰
2023-03-14

我有一个Springboot应用程序,其中配置了一些驼峰路线。

public class CamelConfig {
    private static final Logger LOG = LoggerFactory.getLogger(CamelConfig.class);

    @Value("${activemq.broker.url:tcp://localhost:61616}")
    String brokerUrl;

    @Value("${activemq.broker.maxconnections:1}")
    int maxConnections;

    @Bean
    ConnectionFactory jmsConnectionFactory() {
        PooledConnectionFactory pooledConnectionFactory = new PooledConnectionFactory(new ActiveMQConnectionFactory(brokerUrl));
        pooledConnectionFactory.setMaxConnections(maxConnections);
        return pooledConnectionFactory;
    }

    @Bean
    public RoutesBuilder route() {
        LOG.info("Initializing camel routes......................");
        return new SpringRouteBuilder() {
            @Override
            public void configure() throws Exception {
                from("activemq:testQueue")
                  .to("bean:queueEventHandler?method=handleQueueEvent");
            }
        };
    }
}

我想测试从activemq:testQueuequeueEventHandler::handleQueueEvent的路由。我试过这里提到的不同东西http://camel.apache.org/camel-test.html,但似乎无法让它工作。

我正在尝试这样做:

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = {CamelConfig.class,   CamelTestContextBootstrapper.class})
    public class CamelRouteConfigTest {

    @Produce(uri = "activemq:testQueue")
    protected ProducerTemplate template;

    @Test
    public void testSendMatchingMessage() throws Exception {
        template.sendBodyAndHeader("testJson", "foo", "bar");
        // Verify handleQueueEvent(...) method is called on bean queueEventHandler by mocking
    }

但是我的ProducerTemplate总是null。我尝试了自动连接CamelContext,但遇到一个异常,它无法解析CamelContext。但这可以通过添加上下文来解决。类@SpringBootTest类。但是我的ProducerTemplate仍然是null

请建议。我使用的是Camel 2.18和Spring Boot 1.4。

共有3个答案

白文彬
2023-03-14

我最后是这样做的:

    @RunWith(SpringRunner.class)
    public class CamelRouteConfigTest extends CamelTestSupport {
    
        private static final Logger LOG = LoggerFactory.getLogger(CamelRouteConfigTest.class);
        private static BrokerService brokerSvc = new BrokerService();
    
        @Mock
        private QueueEventHandler queueEventHandler;
    
        @BeforeClass
        // Sets up an embedded broker
        public static void setUpBroker() throws Exception {
            brokerSvc.setBrokerName("TestBroker");
            brokerSvc.addConnector("tcp://localhost:61616");
            brokerSvc.setPersistent(false);
            brokerSvc.setUseJmx(false);
            brokerSvc.start();
        }
    
        @Override
        protected RoutesBuilder createRouteBuilder() throws Exception {
            return new CamelConfig().route();
        }
    
        // properties in .yml has to be loaded manually. Not sure of .properties file
        @Override
        protected Properties useOverridePropertiesWithPropertiesComponent() {
            YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
            try {
                PropertySource<?> applicationYamlPropertySource = loader.load(
                    "properties", new ClassPathResource("application.yml"),null);// null indicated common properties for all profiles.
                Map source = ((MapPropertySource) applicationYamlPropertySource).getSource();
                Properties properties = new Properties();
                properties.putAll(source);
                return properties;
            } catch (IOException e) {
                LOG.error("application.yml file cannot be found.");
            }
    
            return null;
        }
    
        @Override
        protected JndiRegistry createRegistry() throws Exception {
            JndiRegistry jndi = super.createRegistry();
            MockitoAnnotations.initMocks(this);
            jndi.bind("queueEventHandler", queueEventHandler);
    
            return jndi;
        }
    
        @Test
        // Sleeping for a few seconds is necessary, because this line template.sendBody runs in a different thread and
        // CamelTest takes a few seconds to do the routing.
        public void testRoute() throws InterruptedException {
            template.sendBody("activemq:productpushevent", "HelloWorld!");
            Thread.sleep(2000);
            verify(queueEventHandler, times(1)).handleQueueEvent(any());
        }
    
        @AfterClass
        public static void shutDownBroker() throws Exception {
            brokerSvc.stop();
        }
    }
曾奇略
2023-03-14

对于使用MQ和Spring Boot的一条路由,如下所示:

    @Component
    public class InboundRoute extends RouteBuilder {
    
      @Override
      public void configure() {
        JaxbDataFormat personDataFormat = new JaxbDataFormat();
        personDataFormat.setContextPath(Person.class.getPackage().getName());
        personDataFormat.setPrettyPrint(true);
        from("direct:start").id("InboundRoute")
            .log("inbound route")
            .marshal(personDataFormat)
            .to("log:com.company.app?showAll=true&multiline=true")
            .convertBodyTo(String.class)
            .inOnly("mq:q.empi.deim.in")
            .transform(constant("DONE"));
      }
    }

为了替换endpoint并仅使用模拟,我使用了Advicewith:

    @RunWith(CamelSpringBootRunner.class)
    @UseAdviceWith
    @SpringBootTest(classes = InboundApp.class)
    @MockEndpoints("mock:a")
    public class InboundRouteCamelTest {
    
      @EndpointInject(uri = "mock:a")
      private MockEndpoint mock;
    
      @Produce(uri = "direct:start")
      private ProducerTemplate template;
    
      @Autowired
      private CamelContext context;
    
      @Test
      public void whenInboundRouteIsCalled_thenSuccess() throws Exception {
        mock.expectedMinimumMessageCount(1);
        RouteDefinition route = context.getRouteDefinition("InboundRoute");
        route.adviceWith(context, new AdviceWithRouteBuilder() {
          @Override
          public void configure() {
            weaveByToUri("mq:q.empi.deim.in").replace().to("mock:a");
          }
        });
        context.start();
    
        String response = (String) template.requestBodyAndHeader("direct:start",
            getSampleMessage("/SimplePatient.xml"), Exchange.CONTENT_TYPE, MediaType.APPLICATION_XML);
    
        assertThat(response).isEqualTo("DONE");
        mock.assertIsSatisfied();
      }
    
      private String getSampleMessage(String filename) throws Exception {
        return IOUtils
            .toString(this.getClass().getResourceAsStream(filename), StandardCharsets.UTF_8.name());
      }
    }

我使用以下依赖项:Spring Boot 2.1.4-RELEASE和Camel 2.23.2。完整的源代码可在Github上获得。

慕容超
2023-03-14

在支持Spring Boot 2的Camel 2.22.0和Continuous中,您可以使用以下模板测试支持Spring Boot 2的路由:

@RunWith(CamelSpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.NONE, classes = {
    Route1.class,
    Route2.class,
    ...
})
@EnableAutoConfiguration
@DisableJmx
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class RouteTest {

  @TestConfiguration
  static class Config {
    @Bean
    CamelContextConfiguration contextConfiguration() {
      return new CamelContextConfiguration() {
        @Override
        public void beforeApplicationStart(CamelContext camelContext) {
          // configure Camel here
        }

        @Override
        public void afterApplicationStart(CamelContext camelContext) {
          // Start your manual routes here
        }
      };
    }

    @Bean
    RouteBuilder routeBuilder() {
      return new RouteBuilder() {
        @Override
        public void configure() {
          from("direct:someEndpoint").to("mock:done");
        }
      };
    }

    // further beans ...
  }

  @Produce(uri = "direct:start")
  private ProducerTemplate template;
  @EndpointInject(uri = "mock:done")
  private MockEndpoint mockDone;

  @Test
  public void testCamelRoute() throws Exception {
    mockDone.expectedMessageCount(1);

    Map<String, Object> headers = new HashMap<>();
    ...
    template.sendBodyAndHeaders("test", headers);

    mockDone.assertIsSatisfied();
  }
}

Spring Boot区分了@Configuration@TestConfiguration。primer one将替换任何现有配置(如果在顶级类上进行了注释),而除了其他配置之外,还将运行@TestConfiguration

此外,在更大的项目中,您可能会遇到自动配置问题,因为您不能依靠Spring Boot 2来配置自定义数据库池或其他不正确的配置,或者在您有特定目录结构且配置不在直接祖先目录中的情况下。在这种情况下,最好省略@EnableAutoConfiguration注释。为了让Spring仍然自动配置Camel,只需传递Camel自动配置。类中提到的类@SpringBootTest

@SpringBootTest(webEnvironment = WebEnvironment.NONE, classes = {
    Route1.class,
    Route2.class,
    RouteTest.Config.class,
    CamelAutoConfiguration.class
}

由于不执行自动配置,Spring不会在测试类中加载测试配置,也不会初始化Camel。通过手动将这些配置添加到引导类中,Spring会帮你完成。

 类似资料:
  • 问题内容: 我尝试对Apache骆驼路线进行junit测试。像这样的东西: 构建器类的定义如下 “ myExportRouteProcessor”类仅从JPA存储库中获取一些数据,并将结果放入路由。我想要的是在测试类中触发此路由,以检查整个过程是否正确完成。当前,处理器未启动。我该怎么办? 问题答案: 您可以使用AdviceWithRouteBuilder#replaceFromWith直接替换测

  • 我试着为阿帕奇骆驼路线做一个jUnit测试。类似于这样: builder类的定义如下 myExportRouteProcencer类只是从JPA存储库中获取一些数据,并将结果放入路由。我想要的是在测试类中触发此路由,以检查整个过程是否正确完成。目前,处理器没有被触发。我应该做些什么?

  • 问题内容: 我一直在仔细研究Apache Camel文档,试图对它的两个 最基本 概念(端点和路由)有一个具体的了解,尽管这些术语在文档中各处都使用,但是我找不到真正定义它们的参考。是以及它们的用途。尽管它们的名称听起来很明显,而且我 想 我理解它们的含义,但是现在我已被分配到一项使我深深陷入Apache Camel Land的任务,而了解这些机制的绝对至关重要是。 我的猜测是,“端点”只是一个b

  • 嗨,我在camel中有一个JMS消费者路由,我的要求是在特定事件时停止/暂停该路由(基于某个字段值),然后使用调度器恢复该路由。为此,我创建了两个路由,一个是我的原始jms消费者路由,另一个是调度程序路由,它们恢复jms消费者路由,虽然我能够暂停路由,但第二个路由不恢复暂停的路由,它显示的状态为已启动。 以下是我的两条路线 请帮助我如何实现上述场景。

  • 我通过以下代码以编程方式创建JMS路由: 我有课: 我想在上述路由和endpoint之间交换一些信息/参数。根据我想要的参数值,选择要在这个消息侦听器容器中设置的连接工厂。 请让我知道我是否能够解释我的问题陈述。 还有其他方法可以实现这一点吗?我想在运行时构建连接工厂,路由也是如此。JmsEndpoint 中是否有任何方法可以用来了解路由 id?

  • 我设置了一个endpoint,如下所示: 我用骆驼石英2.22.2和石英1.8.6 下面是从关闭到启动上下文的日志。