我正在为一些使用 Apache Camel 路由和 Spring 注入(inject)端点处理程序的遗留代码编写单元测试。这在生产中效果很好,但对于使用 EasyMock 进行单元测试会出现问题,因为 Apache Camel 是多线程的,并且会吞掉来自 EasyMock 的意外方法调用
异常。
我很想使用模拟端点,但应用程序的可配置性不足以在不进行一些重构的情况下做到这一点。我想在进行重构之前进行测试。
基本上我有一条大致如下所示的路线:
from("direct:input")
.to("bean:validatorService?method=validate(${header},${body})")
.choice()
.when(body().isNotNull())
.to("bean:processingService?method=continueProcessing(${header},${body})")
.end()
现在我像平常一样设置单元测试,并使用 EasyMock 创建一个“validatorService”bean。这对于积极的情况非常有用,我可以使用 EasyMock 期望 validatorService.validate
被调用一次。但是,如果接下来调用 processingService.continueProcessing
,我不会收到 EasyMock 异常。我的猜测是camel在另一个线程中吞下了异常(这个猜测与我查看过的camel调试日志一致)。
这是一个按预期工作的测试,这两种方法都应该被调用: EasyMock.reset(mockedValidator,mockedProcessor);
EasyMock.expect(mockedValidator.validate(
EasyMock.anyObject(), EasyMock.anyObject()))
.andReturn("foo").once();
// This method is called, the test passes regardless of whether
// or not the expectation is set because Camel swallows the exception.
//EasyMock.expect(mockedProcessor.continueProcessing(
// EasyMock.anyObject(), EasyMock.anyObject()).once();
EasyMock.replay(mockedValidator, mockedProcessor);
inputProducer.sendBody("message");
verify(mockedValidator, mockedProcessor);
如果有一个“none()”与“once()”和“times(N)”配合,所有这些都可以解决。但我找不到。
最佳答案
这个评论确实是一个很好的评论。 Camel 提供了一个具有良好断言和验证的测试框架。所以我建议使用它。
然后,对于线程中的异常,技巧通常是使用Thread.setUncaughtExceptionHandler
来捕获它们。
然而,事实上,在你的情况下, Camel 可能正在使用它自己的错误系统。我不记得默认值是什么,但您可能想以特定方式管理异常。
最后,你使用了一个很好的模拟吗?
因为如果未调用预期的方法,EasyMock 中的默认模拟应该在 verify
上抛出错误。这就是为什么你并不真正需要none
关于java - EasyMock断言异常被线程吞没,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33807097/