Camel 不能在同一个测试类中两次通知同一个端点

pcww981p  于 12个月前  发布在  Apache
关注(0)|答案(1)|浏览(116)

我有一个测试类,它有一个String isMockEndpointsAndSkip() { return ("*") }来测试一些东西,这使得其他类抱怨,下面的例外java.lang.IllegalArgumentException: Cannot advice route as there are no routes

  • quarkus-core版本:2.16.9.Final
  • quarkus-camel-bom版本:2.16.9.Final

我开始用两条AdviceWith语句更改类,并尝试运行测试,一条通过,另一条失败。通过使用quarkus.log.category."org.apache.camel".level=DEBUG启用调试,我发现在第一次测试之后,Camel上下文似乎被删除了。
我有一个测试类,它是这样的:

@QuarkusTest
public class DispatcherProcessorTest extends CamelQuarkusTestSupport {

    @Inject
    DispatcherProcessor dispatcherProcessor;

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

    /**
     * Tests that when a "recipient setting" doesn't contain an RBAC group's
     * UUID, the exchange is sent to the {@link Routes#FETCH_USERS} route.
     */
    @Test
    void testSendFetchUsers() throws Exception {
        // Create an exchange with an empty body.
        final Exchange exchange = this.createExchangeWithBody("");

        // Create a recipient settings object without the group's UUID.
        final RecipientSettings recipientSettings = new RecipientSettings(
            true,
            true,
            null,
            new HashSet<>()
        );

        // Set the property that will be grabbed in the processor.
        exchange.setProperty(ExchangeProperty.RECIPIENT_SETTINGS, List.of(recipientSettings));

        // Assert that the exchange was sent to the correct route.
        AdviceWith.adviceWith(this.context(), EngineToConnectorRouteBuilder.ENGINE_TO_CONNECTOR, a -> {
            a.mockEndpointsAndSkip(String.format("direct:%s", Routes.FETCH_USERS));
            a.mockEndpointsAndSkip(String.format("direct:%s", Routes.FETCH_GROUP));
        });
        this.startCamelContext();
        this.context().start();

        final MockEndpoint fetchUsersEndpoint = this.getMockEndpoint(String.format("mock:direct:%s", Routes.FETCH_USERS));
        final MockEndpoint fetchGroupEndpoint = this.getMockEndpoint(String.format("mock:direct:%s", Routes.FETCH_GROUP));

        fetchUsersEndpoint.expectedMessageCount(1);
        fetchGroupEndpoint.expectedMessageCount(0);

        this.dispatcherProcessor.process(exchange);

        fetchUsersEndpoint.assertIsSatisfied();
        fetchGroupEndpoint.assertIsSatisfied();

        // Make sure that the exchange contains the "RecipientSettings" object
        final List<Exchange> exchanges = fetchUsersEndpoint.getExchanges();
        final Exchange sentExchange = exchanges.get(0);
        final RecipientSettings sentRecipientSettings = sentExchange.getProperty(ExchangeProperty.CURRENT_RECIPIENT_SETTINGS, RecipientSettings.class);

        Assertions.assertEquals(recipientSettings, sentRecipientSettings, "the recipient settings object was not properly set in the dispatcher");
    }

    /**
     * Tests that when a "recipient setting" contains an RBAC group's UUID,
     * the exchange is sent to the {@link Routes#FETCH_GROUP} route.
     */
    @Test
    void testSendFetchGroup() throws Exception {
        // Create an exchange with an empty body.
        final Exchange exchange = this.createExchangeWithBody("");

        // Create a recipient settings object with the group's UUID.
        final RecipientSettings recipientSettings = new RecipientSettings(
            true,
            true,
            UUID.randomUUID(),
            new HashSet<>()
        );

        // Set the property that will be grabbed in the processor.
        exchange.setProperty(ExchangeProperty.RECIPIENT_SETTINGS, List.of(recipientSettings));

        // Assert that the exchange was sent to the correct route.
        AdviceWith.adviceWith(this.context(), EngineToConnectorRouteBuilder.ENGINE_TO_CONNECTOR, a -> {
            a.mockEndpointsAndSkip(String.format("direct:%s", Routes.FETCH_USERS));
            a.mockEndpointsAndSkip(String.format("direct:%s", Routes.FETCH_GROUP));
        });
        this.startCamelContext();
        this.context().start();

        final MockEndpoint fetchUsersEndpoint = this.getMockEndpoint(String.format("mock:direct:%s", Routes.FETCH_USERS));
        final MockEndpoint fetchGroupEndpoint = this.getMockEndpoint(String.format("mock:direct:%s", Routes.FETCH_GROUP));

        fetchUsersEndpoint.expectedMessageCount(0);
        fetchGroupEndpoint.expectedMessageCount(1);

        this.dispatcherProcessor.process(exchange);

        fetchUsersEndpoint.assertIsSatisfied();
        fetchGroupEndpoint.assertIsSatisfied();

        // Make sure that the exchange contains the "RecipientSettings" object
        final List<Exchange> exchanges = fetchGroupEndpoint.getExchanges();
        final Exchange sentExchange = exchanges.get(0);
        final RecipientSettings sentRecipientSettings = sentExchange.getProperty(ExchangeProperty.CURRENT_RECIPIENT_SETTINGS, RecipientSettings.class);

        Assertions.assertEquals(recipientSettings, sentRecipientSettings, "the recipient settings object was not properly set in the dispatcher");
    }
}

但是,第二个测试失败,并显示相同的错误消息:java.lang.IllegalArgumentException: Cannot advice route as there are no routes .我以为这和我两次“建议”同一条路线有关,但我在How do i unit test the same route multiple times using Apache Camel中看到这是完全可以的。
我做错了什么?

byqmnocz

byqmnocz1#

camel-quarkus Zulip聊天中询问后,用户“Christian Kalkhoff”向我指出了解决方案。从本质上讲,使用AdviceWith的关键是确保禁用路由构建器:

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

@Override
public boolean isUseRouteBuilder() {
    return false;
}

根据dkulp's "Apache Camel: Camel Test" page,您需要禁用路由生成器,以便给予Apache Camel时间将建议的路由应用到上下文:

***方法名称:**boolean islogeRouteBuilder()
***说明:**如果从RouteBuilder()或RouteBuilders()返回的路由构建器应该添加到测试中使用的CamelContext中,则应该启动。如果CamelContext在测试中的使用应该在调用测试方法之前自动启动。当使用advice with时返回true。这有助于了解要使用的adviceWith,并且CamelContext不会在adviceWith发生之前启动。此延迟有助于确保在CamelContext启动之前已设置advice with been属性。

不过,我还没能在这个项目上运行./mvnw clean test,因为我最终还是遇到了同样的错误。为了能够做到这一点,I still need to put @TestProfile(TestClassName.class) in the test class's annotation

***要强制Quarkus JUnit Extension为给定的测试类重新启动应用程序(以及CamelContext),您需要为该类分配唯一的@io.quarkus.test.junit.TestProfile。**查看Quarkus文档了解如何执行此操作。(请注意,@io.quarkus.test.common.QuarkusTestResource具有类似的效果。

正如文档中所述,性能不佳,但至少我可以运行所有测试。

相关问题