I have defined the following route:
from(direct(Routes.SEND_EMAIL_BOP_SINGLE_PER_USER))
.routeId(Routes.SEND_EMAIL_BOP_SINGLE_PER_USER)
// Split the usernames on an individual exchange each. This property is a Set<String>.
.split(simpleF("${exchangeProperty.%s}", ExchangeProperty.USERNAMES))
// Set the flag for the next route's processor.
.setProperty(ExchangeProperty.SINGLE_EMAIL_PER_USER, constant(true))
.to(direct(Routes.SEND_EMAIL_BOP))
.end();
And written the following test:
@QuarkusTest
public class EmailRouteBuilderTest extends CamelQuarkusTestSupport {
@Inject
ProducerTemplate producerTemplate;
@Override
public String isMockEndpoints() {
return "*";
}
@Test
void testIndividualEmailPerUser() throws InterruptedException {
final Set<String> usernames = Set.of("a", "b", "c", "d", "e");
final Exchange exchange = this.createExchangeWithBody("");
exchange.setProperty(ExchangeProperty.USERNAMES, usernames);
final MockEndpoint sendEmailBopEndpoint = this.getMockEndpoint(String.format("mock:direct:%s", Routes.SEND_EMAIL_BOP), false);
sendEmailBopEndpoint.expectedMessageCount(5);
this.producerTemplate.send(String.format("direct:%s", Routes.SEND_EMAIL_BOP_SINGLE_PER_USER), exchange);
sendEmailBopEndpoint.assertIsSatisfied();
}
}
However, when I run the test, I see all sorts of error messages from the Routes.SEND_EMAIL_BOP
route, which attempts to contact the real service, and the assertion fails with "expected 5 messages, 0 received". The logs indicate the following:
2023-08-31 09:51:55,896 INFO [org.apa.cam.com.moc.InterceptSendToMockEndpointStrategy] (main) Adviced endpoint [direct://send-email-single-per-user] with mock endpoint [mock:direct:send-email-single-per-user]
2023-08-31 09:51:55,897 INFO [org.apa.cam.com.moc.InterceptSendToMockEndpointStrategy] (main) Adviced endpoint [direct://send-email-bop] with mock endpoint [mock:direct:send-email-bop]
2023-08-31 09:51:55,896 INFO [org.apa.cam.com.moc.InterceptSendToMockEndpointStrategy] (main) Adviced endpoint [http://boplocalhost:9999] with mock endpoint [mock:http:boplocalhost:9999]
The last line of the log corresponds to the service. I think I am understanding this whole thing wrong: I thought that mocking the endpoints made Camel not call the real services or the subsequent routes.
I have tried replacing isMockEndpoints
with isMockEndpointsAndSkip
but then the test doesn't work as well.
May you please help me understanding what I am doing wrong?
Thank you very much in advance.
EDIT: Updated code with "adviceWith":
@QuarkusTest
public class EmailRouteBuilderTest extends CamelQuarkusTestSupport {
@Inject
ProducerTemplate producerTemplate;
@Override
public boolean isUseAdviceWith() {
return true;
}
@Test
void testIndividualEmailPerUser() throws Exception {
AdviceWith.adviceWith(this.context, Routes.SEND_EMAIL_BOP, a -> {
a.mockEndpointsAndSkip("*");
});
final Set<String> usernames = Set.of("a", "b", "c", "d", "e");
final Exchange exchange = this.createExchangeWithBody("");
exchange.setProperty(ExchangeProperty.USERNAMES, usernames);
final MockEndpoint sendEmailBopEndpoint = this.getMockEndpoint(String.format("mock:direct:%s", Routes.SEND_EMAIL_BOP), false);
sendEmailBopEndpoint.expectedMessageCount(5);
this.producerTemplate.send(String.format("direct:%s", Routes.SEND_EMAIL_BOP_SINGLE_PER_USER), exchange);
sendEmailBopEndpoint.assertIsSatisfied();
}
}
This generates the following error message:
2023-09-04 10:11:34,767 WARN [org.apa.cam.sup.EventHelper] (main) Error notifying event 85D6EC0051F6FCF-0000000000000000 exchange completed took: 5ms. This exception will be ignored.: java.lang.NullPointerException: Cannot invoke "org.apache.camel.Endpoint.getEndpointUri()" because "endpoint" is null
And makes the test fail as well:
java.lang.AssertionError: mock://direct:send-email-bop Received message count. Expected: <5> but was: <0>
Expected :<5>
Actual :<0>
Thanks to Vignesh's comment, I was able to make it work. Notice the route specification in the AdviceWith.adviceWith
:
@QuarkusTest
public class EmailRouteBuilderTest extends CamelQuarkusTestSupport {
@Inject
ProducerTemplate producerTemplate;
@Override
public boolean isUseAdviceWith() {
return true;
}
@Test
void testIndividualEmailPerUser() throws Exception {
AdviceWith.adviceWith(this.context, Routes.SEND_EMAIL_BOP_SINGLE_PER_USER, a -> {
a.mockEndpointsAndSkip(String.format("direct:%s", Routes.SEND_EMAIL_BOP));
});
final Set<String> usernames = Set.of("a", "b", "c", "d", "e");
final Exchange exchange = this.createExchangeWithBody("");
exchange.setProperty(ExchangeProperty.USERNAMES, usernames);
final MockEndpoint sendEmailBopEndpoint = this.getMockEndpoint(String.format("mock:direct:%s", Routes.SEND_EMAIL_BOP), false);
sendEmailBopEndpoint.expectedMessageCount(5);
this.producerTemplate.send(String.format("direct:%s", Routes.SEND_EMAIL_BOP_SINGLE_PER_USER), exchange);
sendEmailBopEndpoint.assertIsSatisfied();
}
}
Initially, I was trying to mock and skip a different route from the one I was testing. With this last change, I'm saying "from this route I'm testing, mock this particular endpoint", which apparently makes Apache mock the endpoint I want.
That makes the test pass!
Posting the comment as answer.
"*" indicates to mock all routes. Specific route should be mocked instead. Ex: "direct:send_email_bop"