Spring boot Spring Boot Apache骆驼路线测试

Spring boot Spring Boot Apache骆驼路线测试,spring-boot,apache-camel,camel-test,Spring Boot,Apache Camel,Camel Test,我有一个Springboot应用程序,其中配置了一些camel路由 public class CamelConfig { private static final Logger LOG = LoggerFactory.getLogger(CamelConfig.class); @Value("${activemq.broker.url:tcp://localhost:61616}") String brokerUrl; @Value("${activemq.broker.maxconnect

我有一个Springboot应用程序,其中配置了一些camel路由

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:testQueue到queueEventHandler::handleQueueEvent的路由 我尝试了这里提到的不同的东西,但似乎都没用

我正试着做这样的事情

@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总是空的。我尝试了自动连接Camelcontext,我得到一个异常,说它无法解析Camelcontext。但这可以通过将SpringCamelContext.class添加到@SpringBootTest类中来解决。但是我的ProducerTemplate仍然是空的


请建议。我正在使用Camel 2.18 Springboot 1.4

您是否尝试使用Camel test runner

@RunWith(CamelSpringJUnit4ClassRunner.class)
如果您使用的是camel-spring引导依赖项,您可能知道它使用自动配置来设置camel:

CamelAutoConfiguration.java

这意味着您可能还需要将@EnableAutoConfiguration添加到测试中。

您是否尝试使用驼峰测试运行程序

@RunWith(CamelSpringJUnit4ClassRunner.class)
如果您使用的是camel-spring引导依赖项,您可能知道它使用自动配置来设置camel:

CamelAutoConfiguration.java

这意味着您可能还需要将@EnableAutoConfiguration添加到您的测试中。

我最后就是这样做的

@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 a 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();
    }
}

我最后就是这样做的

@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 a 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();
    }
}

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

@RunWithCamelSpringRunner.class @SpringBootTestwebEnvironment=WebEnvironment.NONE,类={ 路线1.2级, 路线2.class, ... } @启用自动配置 @DisableJmx @DirtiesContextclassMode=DirtiesContext.ClassMode.AFTER\u类 公共类路由测试{ @测试配置 静态类配置{ @豆子 CamelContextConfiguration上下文配置{ 返回新的CamelContextConfiguration{ @凌驾 public void beforeapplicationstartcammelcontext camelContext{ //在这里配置驼峰 } @凌驾 public void afterApplicationStartCamelContext camelContext{ //从这里开始手动路线 } }; } @豆子 RouteBuilder RouteBuilder{ 返回新RouteBuilder{ @凌驾 公共无效配置{ fromdirect:someEndpoint.tomock:done; } }; } //更多的豆。。。 } @produceri=direct:start 私有产品模板; @EndpointInjecturi=mock:done 私人模拟已完成; @试验 public void testCamelRoute引发异常{ mockDone.expectedMessageCount1; 映射头=新的HashMap; ... template.sendboyandheaderstest,headers; mockDone.assertised; } } Spring Boot区分@Configuration和@TestConfiguration。primer one将替换任何现有配置(如果在顶级类上进行注释),而@TestConfiguration将与其他配置一起运行

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

@SpringBootTestwebEnvironment=WebEnvironment.NONE,类={ 路线1.2级, 路线2.class, RouteTest.Config.class, CamelAutoConfiguration.class }
由于没有执行自动配置,Spring不会在测试类中加载测试配置,也不会初始化Camel。通过手动将这些配置添加到启动类中,Spring将为您完成此操作。

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

@RunWithCamelSpringRunner.class @SpringBootTestwebEnvironment=WebEnvironment.NONE,类={ 路线1.2级, 路线2.class, ... } @启用自动配置 @DisableJmx @DirtiesContextclassMode=DirtiesContext.ClassMode.AFTER\u类 公共类路由测试{ @测试配置 静态类配置{ @豆子 CamelContextConfiguration上下文配置{ 返回新的CamelContextConfiguration{ @凌驾 public void beforeapplicationstartcammelcontext camelContext{ //在这里配置驼峰 } @凌驾 public void afterApplicationStartCamelContext camelContext{ //从这里开始手动路线 } }; } @豆子 RouteBuilder RouteBuilder{ 返回新RouteBuilder{ @凌驾 公共无效配置{ fromdirect:someEndpoint.tomock:done; } }; } //更多的豆。。。 } @produceri=direct:start 私人生产者 后期模板; @EndpointInjecturi=mock:done 私人模拟已完成; @试验 public void testCamelRoute引发异常{ mockDone.expectedMessageCount1; 映射头=新的HashMap; ... template.sendboyandheaderstest,headers; mockDone.assertised; } } Spring Boot区分@Configuration和@TestConfiguration。primer one将替换任何现有配置(如果在顶级类上进行注释),而@TestConfiguration将与其他配置一起运行

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

@SpringBootTestwebEnvironment=WebEnvironment.NONE,类={ 路线1.2级, 路线2.class, RouteTest.Config.class, CamelAutoConfiguration.class }
由于没有执行自动配置,Spring不会在测试类中加载测试配置,也不会初始化Camel。通过手动将这些配置添加到引导类中,Spring将为您完成这项工作。

对于使用MQ和Spring引导的路由,如下所示:

@组成部分 公共类InboundRoute扩展RouteBuilder{ @凌驾 公共无效配置{ JaxbDataFormat personDataFormat=新的JaxbDataFormat; personDataFormat.setContextPathPerson.class.getPackage.getName; personDataFormat.setPrettyPrinttrue; fromdirect:start.idInboundRoute ·登堡路线 .marshalpersonDataFormat .tolog:com.company.app?showAll=true和multiline=true .convertBodyToString.class .inOnlymq:q.empi.deim.in .康斯坦顿; } } 我使用以替换端点并仅使用模拟:

@RunWithCamelSpringBootRunner.class @使用建议 @SpringBootTestclasses=InboundApp.class @工作服:a 公共类边界内路由测试{ @EndpointInjecturi=mock:a 私有模拟端点模拟; @produceri=direct:start 私有产品模板; @自动连线 私人语境; @试验 调用InboundRouteIs时公共无效\u然后成功引发异常{ mock.expectedMinimmumMessageCount1; RouteDefinition route=context.getRouteDefinitionInboundRoute; route.adviceWithcontext,新建AdviceWithRouteBuilder{ @凌驾 公共无效配置{ weaveByToUrimq:q.empi.deim.in.replace.tomock:a; } }; context.start; 字符串响应=字符串模板。requestBodyAndHeaderdirect:start, getSampleMessage/SimplePatient.xml、Exchange.CONTENT\u TYPE、MediaType.APPLICATION\u xml; assertThatresponse.IsequalTone; 模仿、断言化; } 私有字符串getSampleMessageString文件名引发异常{ 返回IOUtils .toStringthis.getClass.getResourceAsStreamfilename,StandardCharsets.UTF_8.name; } }
我使用以下依赖项:Spring Boot 2.1.4-RELEASE和Camel 2.23.2。完整的源代码可在上获得。

用于一个具有MQ和Spring引导的路由,如下所示:

@组成部分 公共类InboundRoute扩展RouteBuilder{ @凌驾 公共无效配置{ JaxbDataFormat personDataFormat=新的JaxbDataFormat; personDataFormat.setContextPathPerson.class.getPackage.getName; personDataFormat.setPrettyPrinttrue; fromdirect:start.idInboundRoute ·登堡路线 .marshalpersonDataFormat .tolog:com.company.app?showAll=true和multiline=true .convertBodyToString.class .inOnlymq:q.empi.deim.in .康斯坦顿; } } 我使用以替换端点并仅使用模拟:

@RunWithCamelSpringBootRunner.class @使用建议 @SpringBootTestclasses=InboundApp.class @工作服:a 公共类边界内路由测试{ @EndpointInjecturi=mock:a 私有模拟端点模拟; @produceri=direct:start 私有产品模板; @自动连线 私人语境; @试验 调用InboundRouteIs时公共无效\u然后成功引发异常{ mock.expectedMinimmumMessageCount1; RouteDefinition route=context.getRouteDefinitionInboundRoute; route.adviceWithcontext,新建AdviceWithRouteBuilder{ @凌驾 公共无效配置{ weaveByToUrimq:q.empi.deim.in.replace.tomock:a; } }; context.start; 字符串响应=字符串模板。requestBodyAndHeaderdirect:start, getSampleMessage/SimplePatient.xml、Exchange.CONTENT\u TYPE、MediaType.APPLICATION\u xml; assertThatresponse.IsequalTone; 模仿、断言化; } 私有字符串getSampleMessageString文件名引发异常{ 返回IOUtils .toStringthis.getClass.getResourceAsStreamfilename,StandardCharsets.UTF_8.name; } }
我使用以下依赖项:Spring Boot 2.1.4-RELEASE和Camel 2.23.2。完整的源代码可在上获得。

您好,CamelSpringJUnit4ClassRunner已弃用。我让它和这样的东西一起工作。公共类AmqTest扩展了CamelTestSupport{@Override protected RouteBuilder createRouteBuilder引发异常{return new ActiveMqConfig.route;}您好,CamelSpringJUnit4ClassRunner已被弃用。我使用了类似的东西。公共类AmqTest扩展了CamelTestSupport{@Override protected RouteBuilder createRouteBuilder引发异常{返回新的ActiveMqConfig.route;}您能用Git提供完整的路由和测试代码吗?谢谢。@pvpkiran,首先感谢您的共享。模板来自哪里?我正在努力解决这个问题。@ddsultan模板通过CamelTestSupport类解析,因为CamelRouteConfigTest扩展了CamelTestSupport@gurpal2000,谢谢,我查一下。你能提供整个路线吗和Git中的测试代码?谢谢。@pvpkiran,首先感谢您的共享。模板来自哪里?我正在努力解决这个问题。@ddsultan模板通过CamelTestSupport类解析,因为CamelRouteConfigTest扩展了CamelTestSupport@gurpal2000,谢谢,我会检查。@DisableJmx不会禁用JMX,因为测试被标记为run使用SpringRunner,而不是CamelSpringRunner。@realmfoo谢谢你的提示。我正在更新帖子。你知道如何在这个设置中使用属性吗?我在这里查看他们的页面:他们引用了UseOverrideProperties with PropertiesComponent?@RyuS。你试过将@PropertySourceclasspath:some.properties添加到你的配置类吗?@RyuS。还有,可能对您感兴趣you@DisableJmx没有禁用JMX,因为测试被标记为使用SpringRunner而不是CamelSpringRunner运行。@realmfoo谢谢您的提示。我正在更新帖子。您知道如何在这个设置中使用属性吗?我在这里查看他们的页面:他们引用UseOverrideProperties WithPropertiesComponent?@RyuS。您知道吗尝试将@PropertySourceclasspath:some.properties添加到您的配置类?@RyuS。此外,您可能会感兴趣