Camel 在模拟路由的端点时,Assert不满足,最终调用真实的端点

sf6xfgos  于 2023-10-18  发布在  Apache
关注(0)|答案(2)|浏览(107)

我定义了以下路由:

from(direct(Routes.SEND_EMAIL_BOP_SINGLE_PER_USER))
    .routeId(Routes.SEND_EMAIL_BOP_SINGLE_PER_USER)
    // Split the usernames on an individual exchange each. This property is a Set<String>.
    .split(simpleF("${exchangeProperty.%s}", ExchangeProperty.USERNAMES))
        // Set the flag for the next route's processor.
        .setProperty(ExchangeProperty.SINGLE_EMAIL_PER_USER, constant(true))
        .to(direct(Routes.SEND_EMAIL_BOP))
    .end();

并编写了以下测试:

@QuarkusTest
public class EmailRouteBuilderTest extends CamelQuarkusTestSupport {
    @Inject
    ProducerTemplate producerTemplate;

    @Override
    public String isMockEndpoints() {
        return "*";
    }

    @Test
    void testIndividualEmailPerUser() throws InterruptedException {
        final Set<String> usernames = Set.of("a", "b", "c", "d", "e");

        final Exchange exchange = this.createExchangeWithBody("");
        exchange.setProperty(ExchangeProperty.USERNAMES, usernames);

        final MockEndpoint sendEmailBopEndpoint = this.getMockEndpoint(String.format("mock:direct:%s", Routes.SEND_EMAIL_BOP), false);
        sendEmailBopEndpoint.expectedMessageCount(5);

        this.producerTemplate.send(String.format("direct:%s", Routes.SEND_EMAIL_BOP_SINGLE_PER_USER), exchange);

        sendEmailBopEndpoint.assertIsSatisfied();
    }
}

然而,当我运行测试时,我看到来自Routes.SEND_EMAIL_BOP路由的各种错误消息,该路由试图联系真实的服务,Assert失败,并显示“预期的5条消息,接收到0条”。日志显示以下内容:

2023-08-31 09:51:55,896 INFO  [org.apa.cam.com.moc.InterceptSendToMockEndpointStrategy] (main) Adviced endpoint [direct://send-email-single-per-user] with mock endpoint [mock:direct:send-email-single-per-user]
2023-08-31 09:51:55,897 INFO  [org.apa.cam.com.moc.InterceptSendToMockEndpointStrategy] (main) Adviced endpoint [direct://send-email-bop] with mock endpoint [mock:direct:send-email-bop]
2023-08-31 09:51:55,896 INFO  [org.apa.cam.com.moc.InterceptSendToMockEndpointStrategy] (main) Adviced endpoint [http://boplocalhost:9999] with mock endpoint [mock:http:boplocalhost:9999]

日志的最后一行对应于服务。我想我对整件事的理解是错误的:我认为模拟端点使Camel不会调用真实的服务或后续路由。
我试过用isMockEndpointsAndSkip替换isMockEndpoints,但是测试不起作用。
你能帮我理解我做错了什么吗?
先谢谢你。

**编辑:**更新代码“adviceWith”:

@QuarkusTest
public class EmailRouteBuilderTest extends CamelQuarkusTestSupport {
    @Inject
    ProducerTemplate producerTemplate;

    @Override
    public boolean isUseAdviceWith() {
        return true;
    }

    @Test
    void testIndividualEmailPerUser() throws Exception {
        AdviceWith.adviceWith(this.context, Routes.SEND_EMAIL_BOP, a -> {
            a.mockEndpointsAndSkip("*");
        });

        final Set<String> usernames = Set.of("a", "b", "c", "d", "e");

        final Exchange exchange = this.createExchangeWithBody("");
        exchange.setProperty(ExchangeProperty.USERNAMES, usernames);

        final MockEndpoint sendEmailBopEndpoint = this.getMockEndpoint(String.format("mock:direct:%s", Routes.SEND_EMAIL_BOP), false);
        sendEmailBopEndpoint.expectedMessageCount(5);

        this.producerTemplate.send(String.format("direct:%s", Routes.SEND_EMAIL_BOP_SINGLE_PER_USER), exchange);

        sendEmailBopEndpoint.assertIsSatisfied();
    }
}

这将生成以下错误消息:

2023-09-04 10:11:34,767 WARN  [org.apa.cam.sup.EventHelper] (main) Error notifying event 85D6EC0051F6FCF-0000000000000000 exchange completed took: 5ms. This exception will be ignored.: java.lang.NullPointerException: Cannot invoke "org.apache.camel.Endpoint.getEndpointUri()" because "endpoint" is null

也会导致测试失败:

java.lang.AssertionError: mock://direct:send-email-bop Received message count. Expected: <5> but was: <0>
Expected :<5>
Actual   :<0>

感谢Vignesh的评论,我能够让它工作。请注意AdviceWith.adviceWith中的路由规范:

@QuarkusTest
public class EmailRouteBuilderTest extends CamelQuarkusTestSupport {
    @Inject
    ProducerTemplate producerTemplate;

    @Override
    public boolean isUseAdviceWith() {
        return true;
    }

    @Test
    void testIndividualEmailPerUser() throws Exception {
        AdviceWith.adviceWith(this.context, Routes.SEND_EMAIL_BOP_SINGLE_PER_USER, a -> {
            a.mockEndpointsAndSkip(String.format("direct:%s", Routes.SEND_EMAIL_BOP));
        });

        final Set<String> usernames = Set.of("a", "b", "c", "d", "e");

        final Exchange exchange = this.createExchangeWithBody("");
        exchange.setProperty(ExchangeProperty.USERNAMES, usernames);

        final MockEndpoint sendEmailBopEndpoint = this.getMockEndpoint(String.format("mock:direct:%s", Routes.SEND_EMAIL_BOP), false);
        sendEmailBopEndpoint.expectedMessageCount(5);

        this.producerTemplate.send(String.format("direct:%s", Routes.SEND_EMAIL_BOP_SINGLE_PER_USER), exchange);

        sendEmailBopEndpoint.assertIsSatisfied();
    }
}

最初,我试图模仿和跳过一个不同的路线,从一个我正在测试。对于最后一个更改,我说“从我正在测试的这个路由,模拟这个特定的端点”,这显然使Apache模拟我想要的端点。
这样测试就通过了!

uqdfh47h

uqdfh47h1#

将评论作为答案发布。
“*”表示模拟所有路由。具体的路线应该被嘲笑。例如:“直接发送邮件”

zy1mlcev

zy1mlcev2#

模拟端点本质上会导致端点被检测,以便测试可以Assert有关端点的内容,例如。它收到了多少信息。但是,被嘲笑的端点仍然会被执行。Mock-and-skip采取了防止执行原始端点的额外步骤。
不清楚你所说的mock-and-skip是什么意思,它会导致你的测试不能很好地工作。如果需要mock返回存根值,请查看MockEndpoint.whenAnyExchangeReceived()。

相关问题