I am using CamelTestSupport and currently have 2 unit test for 1 routes. Both unit test is to test if exception is thrown, I used AdviceWith to replace and throw Exception.
The issue arises as written in the documentation it is recommended to only Advice the route once as it will cause the 2nd unit test to not match the route.
What can i do to reset the route after each unit test?
The issue arises as written in the documentation it is recommended to only Advice the route once as it will cause the 2nd unit test to not match the route.
Where does it read like this in the documentation?
Using AdviceWith to modify same route in different unit tests seems to work just fine. You should also be able to modify the same route in the same unit tests twice or more for as long the modifications do not conflict with each other.
I would however avoid or at least be very careful when using AdviceWith in methods annotated with @BeforeAll
or @BeforeEach
as these changes will be applied for each test. Same goes for many overridable CamelTestSupport methods.
package com.example;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.builder.AdviceWith;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit5.CamelTestSupport;
import org.junit.jupiter.api.Test;
public class MultiAdviceWithExampleTests extends CamelTestSupport {
class ExceptionA extends Exception {}
class ExceptionB extends Exception {}
@Test
public void exampleThrowsExceptionA() throws Exception{
AdviceWith.adviceWith(context, "example", builder -> {
builder.weaveByToUri("direct:replaceMe")
.replace()
.log("Throwing Exception A")
.throwException(new ExceptionA());
});
MockEndpoint exceptionAMockEndpoint = getMockEndpoint("mock:exceptionA");
MockEndpoint exceptionBMockEndpoint = getMockEndpoint("mock:exceptionB");
exceptionAMockEndpoint.expectedMessageCount(1);
exceptionBMockEndpoint.expectedMessageCount(0);
startCamelContext();
template.sendBody("direct:example", null);
exceptionBMockEndpoint.assertIsSatisfied();
exceptionAMockEndpoint.assertIsSatisfied();
}
@Test
public void exampleThrowsExceptionB() throws Exception{
AdviceWith.adviceWith(context, "example", builder -> {
builder.weaveByToUri("direct:replaceMe")
.replace()
.log("Throwing Exception B")
.throwException(new ExceptionB());
});
MockEndpoint exceptionAMockEndpoint = getMockEndpoint("mock:exceptionA");
MockEndpoint exceptionBMockEndpoint = getMockEndpoint("mock:exceptionB");
exceptionAMockEndpoint.expectedMessageCount(0);
exceptionBMockEndpoint.expectedMessageCount(1);
startCamelContext();
template.sendBody("direct:example", null);
exceptionAMockEndpoint.assertIsSatisfied();
exceptionBMockEndpoint.assertIsSatisfied();
}
@Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:example")
.id("example")
.onException(ExceptionA.class)
.log("Caught exception A")
.to("mock:exceptionA")
.handled(true)
.end()
.onException(ExceptionB.class)
.log("Caught exception A")
.to("mock:exceptionB")
.handled(true)
.end()
.to("direct:replaceMe")
;
from("direct:replaceMe")
.routeId("replaceMe")
.log("should not be displayed.");
}
};
}
@Override
public boolean isUseAdviceWith() {
return true;
}
}
Since overriding the isUseAdviceWith
method to return true forces one to start camel context manually for each tests I am assuming that CamelTestsSupport
either creates separate context and routes for each tests or at least resets the routes and mock endpoints to their original states between tests.
Both unit test is to test if exception is thrown, I used AdviceWith to replace and throw Exception.
If you're using JUnits assertThrows
it might not work as you expect with Apache Camel as Camel will likely throw one of it's own Exceptions instead. To get the original Exception you can use template.send
and get the resulting exception from the resulting exchange through .getException().getClass()
.
// Remove the onException blocks from route with this
// or getException() will return null
Exchange result = template.send("direct:example", new DefaultExchange(context));
assertEquals(ExceptionB.class, result.getException().getClass());