微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

测试时没有骆驼消费者可用于 direct-vm 类型的路由

如何解决测试时没有骆驼消费者可用于 direct-vm 类型的路由

我正在使用 Camel 进行单元测试,当我从 Camel In Action 存储库执行 this test 时,它运行良好,但是当我将路由类型从 SEDA 更改为 direct-vm它失败并显示以下消息:

引起:org.apache.camel.component.directvm.DirectVmConsumerNotAvailableException:端点上没有可用的消费者:direct-vm://camel。交换[ID....

SEDA 和 direct-vm 这两种类型的区别在于,第一种是异步的,第二种是同步的。这就是测试失败的原因吗?如何使测试适用于 direct-vm 类型的路由?

我使用的是 JDK 1.8 和 Camel 2.25.2

更新:我发现 adviceWith 中的 mockEndpoints() 方法存在问题,路由没有被模拟。这是我启动测试时打印在日志中的内容

2021-07-20 16:27:36.501  INFO 31220 --- [           main] org.apache.camel.model.RouteDeFinition   : Adviced route before/after as XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<route xmlns="http://camel.apache.org/schema/spring" customId="true" id="basicRoute">
    <from uri="direct-vm:quotes"/>
    <choice id="choice2">
        <when id="when2">
            <simple>${body} contains 'Camel'</simple>
            <log id="log4" loggingLevel="INFO" message="camel route"/>
            <to id="to11" uri="direct-vm:camel"/>
        </when>
        <otherwise id="otherwise2">
            <log id="log5" loggingLevel="INFO" message="other route"/>
            <to id="to12" uri="direct-vm:other"/>
        </otherwise>
    </choice>
</route>

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<route xmlns="http://camel.apache.org/schema/spring" customId="true" id="basicRoute">
    <from uri="direct-vm:hitme"/>
    <choice id="choice2">
        <when id="when2">
            <simple>${body} contains 'Camel'</simple>
            <log id="log4" loggingLevel="INFO" message="camel route"/>
            <to id="to11" uri="direct-vm:camel"/>
        </when>
        <otherwise id="otherwise2">
            <log id="log5" loggingLevel="INFO" message="other route"/>
            <to id="to12" uri="direct-vm:other"/>
        </otherwise>
    </choice>
</route>

但是如果我使用 weaveByToUri 来模拟路由:

weaveByToUri("direct-vm:camel").replace().to("mock:direct-vm:camel");
weaveByToUri("direct-vm:other").replace().to("mock:direct-vm:other");

模拟路由并且测试有效:

2021-07-20 16:30:42.409  INFO 9920 --- [           main] org.apache.camel.model.RouteDeFinition   : Adviced route before/after as XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<route xmlns="http://camel.apache.org/schema/spring" customId="true" id="basicRoute">
    <from uri="direct-vm:quotes"/>
    <choice id="choice2">
        <when id="when2">
            <simple>${body} contains 'Camel'</simple>
            <log id="log4" loggingLevel="INFO" message="camel route"/>
            <to id="to11" uri="direct-vm:camel"/>
        </when>
        <otherwise id="otherwise2">
            <log id="log5" loggingLevel="INFO" message="other route"/>
            <to id="to12" uri="direct-vm:other"/>
        </otherwise>
    </choice>
</route>

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<route xmlns="http://camel.apache.org/schema/spring" customId="true" id="basicRoute">
    <from uri="direct-vm:hitme"/>
    <choice id="choice2">
        <when id="when2">
            <simple>${body} contains 'Camel'</simple>
            <log id="log4" loggingLevel="INFO" message="camel route"/>
            <pipeline>
                <to uri="mock:direct-vm:camel"/>
            </pipeline>
        </when>
        <otherwise id="otherwise2">
            <log id="log5" loggingLevel="INFO" message="other route"/>
            <pipeline>
                <to uri="mock:direct-vm:other"/>
            </pipeline>
        </otherwise>
    </choice>
</route>

这应该是 mockEndpoints 方法中的错误吗?

解决方法

如果您想在测试中使用 direct-vm,您必须运行另一个 CamelContext,其中包含您要测试的 direct-vm 端点的使用者。您可以使用 Main 类来执行此操作。

public class Example extends CamelTestSupport {
    
    @Override
    protected CamelContext createCamelContext() throws Exception {
        return new DefaultCamelContext();
    }

    @Override
    protected RoutesBuilder createRouteBuilder() throws Exception {
        return new RouteBuilder(){

            @Override
            public void configure() throws Exception {
              
                from("direct-vm:helloReceiver")
                    .routeId("helloReceiver")
                    .log("Message received: ${body}")
                    .to("mock:result");
            }
        };
    }

    @Test
    public void testDirectVM() throws Exception{

        RouteBuilder builder = new RouteBuilder(){

            @Override
            public void configure() throws Exception {
              
                from("direct:helloSender")
                    .routeId("helloSender")
                    .to("direct-vm:helloReceiver");
            }
        };
        
        MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
        mockEndpoint.expectedMessageCount(1);
        mockEndpoint.message(0).body().isEqualTo("hello");

        Main camelMain = new Main();
        camelMain.addRouteBuilder(builder);
        camelMain.start();

        camelMain.getCamelTemplate()
            .sendBody("direct:helloSender","hello");

        mockEndpoint.assertIsSatisfied();
    }
}

但是,最好将字符串变量与 setter 一起用于直接虚拟机端点,您可以在测试期间轻松更改为模拟端点。给它 id,你可以使用 weaveById 让它返回任何你需要的测试。

,

错误消息 No consumers available on endpoint: ... 通常意味着您有生产者向同步端点发送消息,但没有消费者侦听此端点。

有没有可能你刚刚把制作人改成了direct-vm

顺便说一句:direct-vm 通常用于连接同一 JVM 内但来自不同 Camel 上下文的 Camel 路由。一个例子是在 OSGi 包之间。如果您只有 1 个 Camel 上下文,只需使用 direct

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。