我正在使用camel编写应用程序,以便(最终)在保险丝容器中进行部署。该项目的性质要求我混合和匹配Java和XML DSL。
我无法让模拟框架与蓝图一起正常工作。
这是我的单元测试,完全基于示例here。
public class MockNotWorking extends CamelBlueprintTestSupport {
@Test
public void testAdvisedMockEndpointsWithPattern() throws Exception {
context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() {
@Override
public void configure() throws Exception {
mockEndpoints("log*");
}
});
getMockEndpoint("mock:log:foo").expectedBodiesReceived("Bye World");
getMockEndpoint("mock:result").expectedBodiesReceived("Bye World");
template.sendBody("direct:start", "Hello World");
// additional test to ensure correct endpoints in registry
assertNotNull(context.hasEndpoint("direct:start"));
assertNotNull(context.hasEndpoint("log:foo"));
assertNotNull(context.hasEndpoint("mock:result"));
// only the log:foo endpoint was mocked
assertNotNull(context.hasEndpoint("mock:log:foo"));
assertNull(context.hasEndpoint("mock:direct:start"));
assertNull(context.hasEndpoint("mock:direct:foo"));
assertMockEndpointsSatisfied();
}
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:start").to("direct:foo").to("log:foo").to("mock:result");
from("direct:foo").transform(constant("Bye World"));
}
};
}
protected String getBlueprintDescriptor() {
return "OSGI-INF/blueprint/blueprint.xml";
}
}
我已逐字复制了示例here,并对其进行了稍微修改,因此我们扩展CamelBlueprintTestSupport
而不是CamelTestSupport
。这需要覆盖getBlueprintDescriptor
指向我的蓝图xml,其中我定义了一个非常基本的(并且与测试完全无关)路线:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<camelContext id="validationRoute" xmlns="http://camel.apache.org/schema/blueprint" >
<route id="validation">
<from uri="direct:validation" />
<log message="validating..." />
</route>
</camelContext>
</blueprint>
测试失败了:
java.lang.AssertionError: mock://log:foo Received message count. Expected: <1> but was: <0>
所以这意味着消息没有到达模拟端点。更改CamelBlueprintTestSupport
的{{1}}即可。
那么如何才能让这样的模拟器正常运行蓝图?
答案 0 :(得分:0)
使用蓝图时,它会导入您在蓝图xml文件中定义的所有路由,并将它们添加到CamelContext
。
这会破坏事物的原因是context.getRouteDefinitions().get(0)
不再指的是唯一的路线 - 现在有多个路线。因此,当您添加AdviceWithRouteBuilder
时,可能会将其添加到错误的路径中。
以下代码修复了问题(并且也适用于非蓝图测试):
List<RouteDefinition> routes = context.getRouteDefinitions();
for (int i=0; i<routes.size(); i++) {
context.getRouteDefinitions().get(i).adviceWith(context, new AdviceWithRouteBuilder() {
@Override
public void configure() throws Exception {
// mock all endpoints
mockEndpoints("log*");
}
});
}
======更新==
更好的方法是,不是嘲笑所有路线,通过id找到我们的特定路线,然后应用建议。这意味着首先设置路线ID:
from("direct:start").routeId("start").to("direct:foo").to("log:foo").to("mock:result");
然后按ID查找路线并像以前一样调用adviceWith
:
context.getRouteDefinition("start").adviceWith(context, new AdviceWithRouteBuilder() {
@Override
public void configure() throws Exception {
// mock log endpoints
mockEndpoints("log*");
}
});
答案 1 :(得分:0)
实际上,这取决于您使用的Camel版本,某些方法无法按预期工作。如果我没记错的话,它在2.12之后会有更好的改善。 (2.15更好)
在我遇到Camel单元测试后,我最终记录了所有内容:
http://bushorn.com/unit-testing-apache-camel/
http://bushorn.com/camel-unit-testing-using-mock-endpoint/
顺便说一句,而不是这个&#34; mockEndpoints(&#34; log *&#34;);&#34;,我会这样做:
weaveByToString(&#34; 直接:富&#34;。)后()至(&#34;模拟:登录&#34)。。 (这听起来很奇怪,我知道;))
或者如果您可以设置端点ID
weaveById(&#34;端点-ID-的直接-FOO&#34)之后()至(&#34;模拟:登录&#34);。。
或
weaveAddLast()至(&#34;模拟:登录&#34);