我有一个测试类,其中有一个
String isMockEndpointsAndSkip() { return ("*") }
用于测试一些东西,这使得其他类抱怨以下异常 java.lang.IllegalArgumentException: Cannot advice route as there are no routes
。
quarkus-core
版本:2.16.9.Finalquarkus-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
。我认为这与我两次“建议”同一条路线有关,但我在如何使用 Apache Camel 多次对同一条路线进行单元测试中看到,这完全没问题。
我做错了什么?
camel-quarkus
Zulip 聊天中询问后,用户“Christian Kalkhoff”向我指出了解决方案。本质上,使用 AdviceWith
的关键是确保您禁用路线生成器:
@Override
public boolean isUseAdviceWith() {
return true;
}
@Override
public boolean isUseRouteBuilder() {
return false;
}
根据 dkulp 的“Apache Camel:Camel Test”页面,您需要禁用路由构建器,以便让 Apache Camel 有时间将建议的路由应用到上下文:
- 方法名称: boolean isUseRouteBuilder()
- 描述: 如果从 createRouteBuilder() 或 createRouteBuilders() 返回的路由构建器应添加到 测试中使用的CamelContext应该启动。如果测试中使用CamelContext,则应在调用测试方法之前自动启动。 使用advice with时覆盖并返回true。这有助于了解要使用的adviceWith,并且在advicewith发生之前CamelContext不会启动。这种延迟有助于确保建议在 CamelContext 启动之前已完成属性设置。
不过,我无法在该项目上运行
./mvnw clean test
,因为我最终遇到了同样的错误。为了能够做到这一点,我仍然需要将 @TestProfile(TestClassName.class)
放在测试类的注释中:
- 要强制 Quarkus JUnit Extension 重新启动给定测试类的应用程序(以及 CamelContext),您需要为该类分配唯一的 @io.quarkus.test.junit.TestProfile。 检查 Quarkus 文档了解如何做到这一点。 (请注意,@io.quarkus.test.common.QuarkusTestResource 具有类似的效果。)
正如文档中所述,性能变差,但至少我可以运行所有测试。