在Quarkus集成测试中,如何用Apache Camel MockEndpoint断言消息体多部分?
问题:Apache Camel MockEndpoint如何断言消息体的多个部分?
我编写了如下Quarkus集成测试:
@QuarkusTest @TestInstance(TestInstance.Lifecycle.PER_CLASS) class MyTest extends CamelQuarkusTestSupport { @EndpointInject("mock:my-mock") MockEndpoint myMockEndpoint; @Override protected void doAfterConstruct() throws Exception { adviceWith(context, "my-route", route -> route.weaveById("my-endpoint") .replace() .to("mock:my-mock")); } @Test void myTest() throws Exception { myMockEndpoint.expectedMessageCount(1); // 如何断言接收消息体的多个部分? // 执行测试... myMockEndpoint.assertIsSatisfied(); } }
我知道可以通过以下方式断言整个消息体:
myMockEndpoint.expectedBodiesReceived("Entire body");
但当(XML)负载较大时,我希望断言其中的多个部分。我尝试了如下写法:
myMockEndpoint.expectedBodyReceived() // 返回AssertionClause .body() // 返回MockValueBuilder .contains("Some part") // 返回Predicate .contains("Another part"); // 无法实现
然而上述链式调用无法实现,且仅使用单个contains时断言不生效,无论传入什么值测试都会通过。请问如何使用Apache Camel的MockEndpoint断言接收消息体的多个部分?
解决方案
可以通过以下几种方式实现多部分消息体的断言:
1. 使用Predicate组合多个条件
利用Camel的PredicateBuilder将多个contains条件组合成一个断言,传递给expectedBodyReceived:
import org.apache.camel.builder.PredicateBuilder; @Test void myTest() throws Exception { myMockEndpoint.expectedMessageCount(1); // 组合多个包含条件 var multiCondition = PredicateBuilder.and( body().contains("Some part"), body().contains("Another part") ); myMockEndpoint.expectedBodyReceived(multiCondition); // 执行测试... myMockEndpoint.assertIsSatisfied(); }
这种方式会确保消息体同时包含指定的所有内容。
2. 手动获取消息体后用JUnit断言
在assertIsSatisfied之后,从MockEndpoint取出消息,直接用JUnit的断言方法验证多个部分:
import static org.junit.jupiter.api.Assertions.*; @Test void myTest() throws Exception { myMockEndpoint.expectedMessageCount(1); // 执行测试... myMockEndpoint.assertIsSatisfied(); // 获取接收到的消息体 String body = myMockEndpoint.getExchanges().get(0).getIn().getBody(String.class); // 验证多个部分 assertTrue(body.contains("Some part")); assertTrue(body.contains("Another part")); }
这种方式更灵活,适合需要复杂断言逻辑的场景。
3. 针对XML负载使用XPath断言
如果是XML格式的消息体,可以使用Camel的XPath断言,精准验证指定节点的内容:
import org.apache.camel.builder.xml.XPathBuilder; @Test void myTest() throws Exception { myMockEndpoint.expectedMessageCount(1); // 断言XML中存在指定节点内容 myMockEndpoint.expectedBodyReceived().xpath("//root/node1/text() = 'Some part'"); myMockEndpoint.expectedBodyReceived().xpath("//root/node2/text() = 'Another part'"); // 执行测试... myMockEndpoint.assertIsSatisfied(); }
这种方式比简单的字符串匹配更可靠,避免因XML格式变化(如换行、空格)导致的断言失败。
内容的提问来源于stack exchange,提问作者beatngu13
相关产品推荐
相关产品推荐

