在单元测试中,我想模拟发生Exception
。
由于doTry/doCatch
- 阻止,我希望在“mock:count”端点收到一条消息。为什么这不会发生?为什么Exception
由一般onException
- 块处理?
import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.AdviceWithRouteBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.apache.cxf.binding.soap.SoapFault;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
public class TestClass extends CamelTestSupport {
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
onException(Exception.class)
.log(LoggingLevel.INFO, "outer catch")
.handled(true);
from("direct:start")
.doTry()
.to("mock:exception")
.doCatch(Exception.class)
.log(LoggingLevel.INFO, "inner catch")
.to("mock:count")
.end();
}
};
}
@Test
public void testBlaat() throws Exception {
final SoapFault soapFault = new SoapFault("Something clearly went wrong", SoapFault.FAULT_CODE_CLIENT);
Element detail = soapFault.getOrCreateDetail();
Document doc = detail.getOwnerDocument();
Text tn = doc.createTextNode("Fault details");
detail.appendChild(tn);
context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() {
@Override
public void configure() throws Exception {
interceptSendToEndpoint("mock:exception").throwException(new Exception("test"));
}
});
template.sendBody("direct:start", "start");
MockEndpoint endpoint = getMockEndpoint("mock:count");
endpoint.expectedMessageCount(1);
assertMockEndpointsSatisfied();
}
}
答案 0 :(得分:4)
事实证明,当AdviceWithRouteBuilder
截获路由时,RouteDefinition
的{{1}}无法看到doTry/doCatch
引发的异常,因为它们位于不同的位置通道。解决这个问题的方法是使用模拟端点并从模拟中抛出异常:
AdviceWithRouteBuilder
请参阅:http://camel.465427.n5.nabble.com/question-about-exception-handling-behavior-td5743489.html
另请参阅JIRA上的此问题:https://issues.apache.org/jira/browse/CAMEL-6300 它已在Camel 2.10.5和其他更新版本中修复。
答案 1 :(得分:0)
我不确定为什么会发生这种情况,但我有一个想法。我认为你的上下文在到达你的测试用例之前就开始了,也许你的拦截器设置得太迟了。你能试试以下吗?
添加此方法:
@Override
public boolean isUseRouteBuilder() {
return false;
}
然后使用常规方式使用context.addRoutes(new RouteBuilder(){ .. })
定义路线,而不是覆盖createRouteBuilder
。另外,在这里定义你的拦截器。
在配置路由和拦截器后,在测试用例中运行context.start()
。试着告诉我它是否有效。
<强>更新强>: 1}}不需要覆盖。
<强> UPDATE2:强>
我一直在运行一些测试,我看到了同样的行为。似乎onException总是在doCatch之前触发。此外,如果将isUseRouteBuilder
设置为handled
,则异常不会传播,也不会到达doCatch块。
根据doTry doCatch doFinally的文档,我会理解错误处理程序不适用(当使用doTry ... doCatch .. doFinally然后常规的Camel错误处理程序不适用)但是似乎错误处理程序和onException是不一样的。
另外,我发现了这个:how to handle exception or fault in multiple routes对你有所帮助。
最后一件事:您可以在同一个RouteBuilder中定义拦截器:
true
这有帮助吗?