I'm writing unit tests for some legacy code that uses Apache Camel routes and Spring to inject endpoint handlers. This works great in production but is problematic for unit testing with EasyMock because Apache Camel is multi-threaded and swallows Unexpected method call exceptions from EasyMock.
I'd love to use mock endpoints, but the app isn't configurable enough to do that without some refactoring. I'd like to get tests in before I do that refactoring.
Essentially I have a route that looks approximately like this:
from("direct:input")
.to("bean:validatorService?method=validate(${header},${body})")
.choice()
.when(body().isNotNull())
.to("bean:processingService?method=continueProcessing(${header},${body})")
.end()
Now I setup my unit test like I normally would, and create a "validatorService" bean with EasyMock. This works great for positive case, I can use EasyMock to expect validatorService.validate to be called exactly once. However if processingService.continueProcessing gets called next I don't get the EasyMock exception. My guess is that camel swallows the exception in another thread (this guess is consistent with camel debug logs that I've looked through).
Here is a test that works as expected, both methods should be called: 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);
All this would be solved if there was a "none()" to go with "once()" and "times(N)". But there isn't one I could find.
Aucun commentaire:
Enregistrer un commentaire