Skip to content

Commit

Permalink
CamelTestSupport style of testing apache#3511
Browse files Browse the repository at this point in the history
  • Loading branch information
JiriOndrusek committed Jun 22, 2022
1 parent 303c2ce commit f0e16fa
Show file tree
Hide file tree
Showing 49 changed files with 2,618 additions and 169 deletions.
13 changes: 0 additions & 13 deletions docs/modules/ROOT/examples/components/mybatis-bean.yml

This file was deleted.

13 changes: 0 additions & 13 deletions docs/modules/ROOT/examples/components/mybatis.yml

This file was deleted.

1 change: 0 additions & 1 deletion docs/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,6 @@
*** xref:reference/extensions/mongodb.adoc[MongoDB]
*** xref:reference/extensions/mongodb-gridfs.adoc[MongoDB GridFS]
*** xref:reference/extensions/mustache.adoc[Mustache]
*** xref:reference/extensions/mybatis.adoc[MyBatis]
*** xref:reference/extensions/nats.adoc[Nats]
*** xref:reference/extensions/netty.adoc[Netty]
*** xref:reference/extensions/netty-http.adoc[Netty HTTP]
Expand Down
53 changes: 0 additions & 53 deletions docs/modules/ROOT/pages/reference/extensions/mybatis.adoc

This file was deleted.

13 changes: 13 additions & 0 deletions docs/modules/ROOT/pages/user-guide/testing.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,16 @@ class MyTest {
----

More examples of WireMock usage can be found in the Camel Quarkus integration test source tree such as https://github.com/apache/camel-quarkus/tree/main/integration-tests/geocoder[Geocoder].

== Testing with `CamelTestSupport` in JVM mode

Sometimes you want to use test constructs from Camel (like `MockEndpoint`, `AdviceWith` , ...) in *JVM* mode.

`CamelTestSupport` is not designed to work in Quarkus, you can use `CamelQuarkusTestSupport` instead. Test has to be annotated by `@QuarkusTest` and extend `CamelQuarkusTest` to allow you to use Camel test constructs. Support is based on component `camel-test-junit5`, see https://camel.apache.org/components/3.17.x/others/test-junit5.html[documentation] for more information.

There are several limitations:

* - JUnit does not about Qaurkus, different lifecycle, so the instances in the callbacks are different. Use Quarkus callbacks (see the https://quarkus.io/guides/getting-started-testing#enrichment-via-quarkustestcallback[documentation]). TODO is it the only solution?
* CamelQuarkus lifecycle does not allow to start/stop Camel context. Context is started before execution of the first test and closed after the last one. Test has to be written with consideration of this limitation. If it is not possible to write a test with such limitation, `@TestProfile` could be used. Test profile forces quarkus to restart its engine, therefore it creates a new Camel context (see the https://quarkus.io/guides/getting-started-testing#testing_different_profiles/[documentation] about this feature).
* Camel Quarkus executes the production of beans during the build phase. Because all the tests are build together, exclusion behavior is impl;emented into `CamelQuarkusTestSupport`. If a producer of the specific type and name is used in one tests, the instance will be the same for the rest of the tests.

4 changes: 4 additions & 0 deletions extensions-core/core/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus.arc</groupId>
<artifactId>arc-processor</artifactId>
</dependency>

<!-- camel -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ public class InjectionPointsProcessor {
.createSimple(EndpointInject.class.getName());
private static final DotName PRODUCE_ANNOTATION = DotName
.createSimple(Produce.class.getName());
private static final DotName TEST_SUPPORT_CLASS_NAME = DotName
.createSimple("org.apache.camel.quarkus.test.CamelQuarkusTestSupport");

private static SyntheticBeanBuildItem syntheticBean(DotName name, Supplier<?> creator) {
return SyntheticBeanBuildItem.configure(name)
Expand Down Expand Up @@ -226,12 +228,16 @@ void syntheticBeans(
BuildProducer<SyntheticBeanBuildItem> syntheticBeans,
BuildProducer<NativeImageProxyDefinitionBuildItem> proxyDefinitions) {

Set<String> alreadyCreated = new HashSet<>();

for (AnnotationInstance annot : index.getIndex().getAnnotations(ENDPOINT_INJECT_ANNOTATION)) {
final AnnotationTarget target = annot.target();
switch (target.kind()) {
case FIELD: {
final FieldInfo field = target.asField();
endpointInjectBeans(recorder, syntheticBeans, index.getIndex(), annot, field.type().name());
if (!excludeTestSyntheticBeanDuplicities(annot, alreadyCreated, field.declaringClass(), index.getIndex())) {
endpointInjectBeans(recorder, syntheticBeans, index.getIndex(), annot, field.type().name());
}
break;
}
case METHOD: {
Expand All @@ -251,8 +257,10 @@ void syntheticBeans(
switch (target.kind()) {
case FIELD: {
final FieldInfo field = target.asField();
produceBeans(recorder, capabilities, syntheticBeans, proxyDefinitions, beanCapabilityAvailable,
index.getIndex(), annot, field.type().name(), field.name(), field.declaringClass().name());
if (!excludeTestSyntheticBeanDuplicities(annot, alreadyCreated, field.declaringClass(), index.getIndex())) {
produceBeans(recorder, capabilities, syntheticBeans, proxyDefinitions, beanCapabilityAvailable,
index.getIndex(), annot, field.type().name(), field.name(), field.declaringClass().name());
}
break;
}
case METHOD: {
Expand All @@ -266,6 +274,47 @@ void syntheticBeans(
}
}

private boolean excludeTestSyntheticBeanDuplicities(AnnotationInstance annot, Set<String> alreadyCreated,
ClassInfo declaringClass, IndexView index) {
String identifier = annot.toString(false) + ":" + getTargetClass(annot).toString();

if (extendsCamelQuarkusTest(declaringClass, index)) {
if (alreadyCreated.contains(identifier)) {
// System.out.println(">>>>>>>>>> already exists: " + identifier);
return true;
} else {
// System.out.println(">>>>>>>>>> creating: " + identifier);
alreadyCreated.add(identifier);
}
}
return false;
}

private DotName getTargetClass(AnnotationInstance annot) {
switch (annot.target().kind()) {
case FIELD:
return annot.target().asField().type().name();
case METHOD:
return annot.target().asMethod().returnType().name();
default:
return null;
}
}

private boolean extendsCamelQuarkusTest(ClassInfo declaringClass, IndexView indexView) {
if (declaringClass == null) {
return false;
}

if (TEST_SUPPORT_CLASS_NAME.equals(declaringClass.name())) {
return true;
}

//iterate over parent until found CamelQuarkusTest or null
return (declaringClass.superName() != null &&
extendsCamelQuarkusTest(indexView.getClassByName(declaringClass.superName()), indexView));
}

void produceBeans(CamelRecorder recorder, List<CapabilityBuildItem> capabilities,
BuildProducer<SyntheticBeanBuildItem> syntheticBeans,
BuildProducer<NativeImageProxyDefinitionBuildItem> proxyDefinitions,
Expand Down
1 change: 0 additions & 1 deletion extensions/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@
<module>mongodb</module>
<module>mongodb-gridfs</module>
<module>mustache</module>
<module>mybatis</module>
<module>nats</module>
<module>netty</module>
<module>netty-http</module>
Expand Down
1 change: 0 additions & 1 deletion integration-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@
<module>mllp</module>
<module>mongodb-grouped</module>
<module>mustache</module>
<module>mybatis</module>
<module>nats</module>
<module>netty</module>
<module>nitrite</module>
Expand Down
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@
<module>integration-test-groups</module>
<module>docs</module>
<module>integration-tests-jvm</module>
<module>test-framework</module>
</modules>

<developers>
Expand Down Expand Up @@ -586,6 +587,10 @@
<path>integration-tests-support</path>
<artifactIdPrefix>camel-quarkus-integration-test-support-</artifactIdPrefix>
</extensionDir>
<extensionDir>
<path>test-framework</path>
<artifactIdPrefix>camel-quarkus-test-framework</artifactIdPrefix>
</extensionDir>
</extensionDirs>
</configuration>
</plugin>
Expand Down
Loading

0 comments on commit f0e16fa

Please sign in to comment.