This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push: new 6aae76b CAMEL-17574: Test module for camel-main applications (#6974) 6aae76b is described below commit 6aae76b9f8e57fef08cff53228bde3dceceab4a0 Author: Nicolas Filotto <essob...@users.noreply.github.com> AuthorDate: Thu Feb 17 22:24:56 2022 +0100 CAMEL-17574: Test module for camel-main applications (#6974) --- bom/camel-bom/pom.xml | 5 + catalog/camel-allcomponents/pom.xml | 4 + .../org/apache/camel/test/cdi/AdviceRoute.java | 16 +- .../apache/camel/test/cdi/CamelCdiExtension.java | 16 +- .../{ => camel-test-main-junit5}/pom.xml | 47 ++++-- .../services/org/apache/camel/other.properties | 7 + .../src/generated/resources/test-main-junit5.json | 15 ++ .../src/main/docs/test-main-junit5.adoc | 120 ++++++++++++++ .../test/main/junit5/CamelMainTestSupport.java | 173 +++++++++++++++++++++ .../camel/test/main/junit5/AdviceRouteTest.java | 55 +++++++ .../apache/camel/test/main/junit5/Greetings.java | 30 ++++ .../camel/test/main/junit5/MyConfiguration.java | 40 +++++ .../test/main/junit5/OverridePropertiesTest.java | 53 +++++++ .../camel/test/main/junit5/ReplaceBeanTest.java | 66 ++++++++ .../test/main/junit5/ReplaceRouteFromTest.java | 54 +++++++ ...UseSeveralPropertyPlaceholderLocationsTest.java | 49 ++++++ .../junit5/custom/LoadCustomConfigurationTest.java | 54 +++++++ .../src/test/resources/application.properties | 23 +++ .../test/resources/extra-application.properties | 20 +++ .../src/test/resources/log4j2.properties | 30 ++++ .../junit5/custom/custom-application.properties | 20 +++ .../src/test/resources/routes/my-route.xml | 26 ++++ components/camel-test/pom.xml | 1 + .../others/examples/json/test-main-junit5.json | 1 + docs/components/modules/others/nav.adoc | 1 + .../modules/others/pages/test-main-junit5.adoc | 1 + docs/user-manual/modules/ROOT/pages/testing.adoc | 3 + parent/pom.xml | 5 + 28 files changed, 902 insertions(+), 33 deletions(-) diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml index 5e67aed..a4d7d33 100644 --- a/bom/camel-bom/pom.xml +++ b/bom/camel-bom/pom.xml @@ -2030,6 +2030,11 @@ </dependency> <dependency> <groupId>org.apache.camel</groupId> + <artifactId>camel-test-main-junit5</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> <artifactId>camel-test-parent</artifactId> <version>${project.version}</version> </dependency> diff --git a/catalog/camel-allcomponents/pom.xml b/catalog/camel-allcomponents/pom.xml index c804c3ac..5b0ac540 100644 --- a/catalog/camel-allcomponents/pom.xml +++ b/catalog/camel-allcomponents/pom.xml @@ -1391,6 +1391,10 @@ </dependency> <dependency> <groupId>org.apache.camel</groupId> + <artifactId>camel-test-main-junit5</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> <artifactId>camel-test-spring-junit5</artifactId> </dependency> <dependency> diff --git a/components/camel-test/camel-test-cdi-junit5/src/main/java/org/apache/camel/test/cdi/AdviceRoute.java b/components/camel-test/camel-test-cdi-junit5/src/main/java/org/apache/camel/test/cdi/AdviceRoute.java index be091e3..eaab2df 100644 --- a/components/camel-test/camel-test-cdi-junit5/src/main/java/org/apache/camel/test/cdi/AdviceRoute.java +++ b/components/camel-test/camel-test-cdi-junit5/src/main/java/org/apache/camel/test/cdi/AdviceRoute.java @@ -34,17 +34,17 @@ import org.apache.camel.builder.AdviceWithRouteBuilder; * route whose identifier is <i>main-route</i>. * * <pre> - * { - * @code - * @AdviceRoute("main-route") - * public class ReplaceDirectWithMockBuilder extends AdviceWithRouteBuilder { + * <code> * - * @Override - * public void configure() throws Exception { - * weaveByToUri("direct:out").replace().to("mock:test"); - * } + * @AdviceRoute("main-route") + * public class ReplaceDirectWithMockBuilder extends AdviceWithRouteBuilder { + * + * @Override + * public void configure() throws Exception { + * weaveByToUri("direct:out").replace().to("mock:test"); * } * } + * </code> * </pre> * * @see AdviceWithRouteBuilder diff --git a/components/camel-test/camel-test-cdi-junit5/src/main/java/org/apache/camel/test/cdi/CamelCdiExtension.java b/components/camel-test/camel-test-cdi-junit5/src/main/java/org/apache/camel/test/cdi/CamelCdiExtension.java index 134f4fa..2277fa7 100644 --- a/components/camel-test/camel-test-cdi-junit5/src/main/java/org/apache/camel/test/cdi/CamelCdiExtension.java +++ b/components/camel-test/camel-test-cdi-junit5/src/main/java/org/apache/camel/test/cdi/CamelCdiExtension.java @@ -59,17 +59,17 @@ import org.junit.jupiter.api.extension.TestInstanceFactoryContext; * start-up of the Camel context to ensure that it works as expected. * * <pre> - * { - * @code - * @AdviceRoute("route") - * public class ExternalTestBuilder extends AdviceWithRouteBuilder { + * <code> * - * @Override - * public void configure() throws Exception { - * weaveByToUri("direct:out").replace().to("mock:test"); - * } + * @AdviceRoute("route") + * public class ExternalTestBuilder extends AdviceWithRouteBuilder { + * + * @Override + * public void configure() throws Exception { + * weaveByToUri("direct:out").replace().to("mock:test"); * } * } + * </code> * </pre> * * @see AdviceRoute diff --git a/components/camel-test/pom.xml b/components/camel-test/camel-test-main-junit5/pom.xml similarity index 52% copy from components/camel-test/pom.xml copy to components/camel-test/camel-test-main-junit5/pom.xml index 8595e4b..67eae16 100644 --- a/components/camel-test/pom.xml +++ b/components/camel-test/camel-test-main-junit5/pom.xml @@ -17,28 +17,41 @@ limitations under the License. --> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.apache.camel</groupId> - <artifactId>components</artifactId> + <artifactId>camel-test-parent</artifactId> <version>3.16.0-SNAPSHOT</version> </parent> - <artifactId>camel-test-parent</artifactId> - <packaging>pom</packaging> - <name>Camel :: Test :: Parent</name> - <description>Camel Test parent</description> - - <modules> - <module>camel-test</module> - <module>camel-test-cdi</module> - <module>camel-test-cdi-junit5</module> - <module>camel-test-spring</module> - <module>camel-test-junit5</module> - <module>camel-test-spring-junit5</module> - </modules> - + <artifactId>camel-test-main-junit5</artifactId> + <packaging>jar</packaging> + + <name>Camel :: Test :: Main :: JUnit5</name> + <description>Camel unit testing with Main and JUnit 5</description> + + <properties> + <firstVersion>3.16.0</firstVersion> + <label>testing,java</label> + <title>Test Main JUnit5</title> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-test-junit5</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-main</artifactId> + </dependency> + <!-- test dependencies --> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-xml-io-dsl</artifactId> + <scope>test</scope> + </dependency> + </dependencies> </project> diff --git a/components/camel-test/camel-test-main-junit5/src/generated/resources/META-INF/services/org/apache/camel/other.properties b/components/camel-test/camel-test-main-junit5/src/generated/resources/META-INF/services/org/apache/camel/other.properties new file mode 100644 index 0000000..266d450 --- /dev/null +++ b/components/camel-test/camel-test-main-junit5/src/generated/resources/META-INF/services/org/apache/camel/other.properties @@ -0,0 +1,7 @@ +# Generated by camel build tools - do NOT edit this file! +name=test-main-junit5 +groupId=org.apache.camel +artifactId=camel-test-main-junit5 +version=3.16.0-SNAPSHOT +projectName=Camel :: Test :: Main :: JUnit5 +projectDescription=Camel unit testing with Main and JUnit 5 diff --git a/components/camel-test/camel-test-main-junit5/src/generated/resources/test-main-junit5.json b/components/camel-test/camel-test-main-junit5/src/generated/resources/test-main-junit5.json new file mode 100644 index 0000000..faae66a --- /dev/null +++ b/components/camel-test/camel-test-main-junit5/src/generated/resources/test-main-junit5.json @@ -0,0 +1,15 @@ +{ + "other": { + "kind": "other", + "name": "test-main-junit5", + "title": "Test Main JUnit5", + "description": "Camel unit testing with Main and JUnit 5", + "deprecated": false, + "firstVersion": "3.16.0", + "label": "testing,java", + "supportLevel": "Preview", + "groupId": "org.apache.camel", + "artifactId": "camel-test-main-junit5", + "version": "3.16.0-SNAPSHOT" + } +} diff --git a/components/camel-test/camel-test-main-junit5/src/main/docs/test-main-junit5.adoc b/components/camel-test/camel-test-main-junit5/src/main/docs/test-main-junit5.adoc new file mode 100644 index 0000000..c1a3631 --- /dev/null +++ b/components/camel-test/camel-test-main-junit5/src/main/docs/test-main-junit5.adoc @@ -0,0 +1,120 @@ += Test Main JUnit5 Component +:doctitle: Test Main JUnit5 +:shortname: test-main-junit5 +:artifactid: camel-test-main-junit5 +:description: Camel unit testing with Main and JUnit 5 +:since: 3.16 +:supportlevel: Preview + +*Since Camel {since}* + +The `camel-test-main-junit5` module is used for unit testing Camel launched in Standalone mode with Camel Main. + +The class `org.apache.camel.test.main.junit5.CamelMainTestSupport` is the base class of all the unit test classes of a Camel Main application. It provides the ability to configure and launch Camel like a Camel Main application. + +Maven users will need to add the following dependency to +their `pom.xml` for this component: + +[source,xml] +---- +<dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-test-main-junit5</artifactId> + <scope>test</scope> + <version>x.x.x</version> + <!-- use the same version as your Camel core version --> +</dependency> +---- + +== Configure Camel as a Camel Main application + +A Camel Main application has access to many specific configuration properties that are not available from the base class `CamelTestSupport`. The base class `CamelMainTestSupport` provides the method `configure(MainConfigurationProperties configuration)` that can be overridden in order to configure Camel for the test like a Camel Main application. + +In the next example, the test class `SomeTest` add a configuration class and specify the xml routes to include. + +[source,java] +---- +import org.apache.camel.main.MainConfigurationProperties; +import org.apache.camel.test.main.junit5.CamelMainTestSupport; + +class SomeTest extends CamelMainTestSupport { + + @Override + protected void configure(MainConfigurationProperties configuration) { + // Add a configuration class + configuration.addConfiguration(SomeConfiguration.class); + // Add all the XML routes + configuration.withRoutesIncludePattern("routes/*.xml"); + } + + // Rest of the test class +} +---- + +== Configure a custom property placeholder location + +By default, the property placeholder used is `application.properties` from the default package. There are several ways to configure the location of the property placeholders, you can either provide the file name of the property placeholder or a list of locations. + +=== A list of property placeholder locations + +To provide a comma separated list of location, you can override the method `getPropertyPlaceholderLocations()` to return your custom list of locations. The order in the list matter especially in case of a property defined at several locations, the value of the property found in the first location where it is defined, is used. + +In the next example, the property placeholder locations configured are `extra-application.properties` and `application.properties` both available in the default package. + +[source,java] +---- +class SomeTest extends CamelMainTestSupport { + + @Override + protected String getPropertyPlaceholderLocations() { + return "classpath:extra-application.properties,classpath:application.properties"; + } + + // Rest of the test class +} +---- + +=== The file name of the property placeholder + +For the sake of simplicity, in case you need only one property placeholder location, you can specify the file name of the property placeholder by overriding the method `getPropertyPlaceholderFileName()`. It can infer the location of the property placeholder as it assumes that it is located in the same package as test class. + +In the next example, the method `getPropertyPlaceholderFileName()` has been overridden in the test class `com.somecompany.SomeTest` to return `custom-application.properties` indicating that the actual location of the property placeholder is `classpath:com/somecompany/custom-application.properties`. + +[source,java] +---- +package com.somecompany; + +class SomeTest extends CamelMainTestSupport { + + @Override + protected String getPropertyPlaceholderFileName() { + return "custom-application.properties"; + } + + // Rest of the test class +} +---- + +== Replace an existing bean + +In Camel Main, you have the opportunity to bind custom beans dynamically using the specific annotation `@BindToRegistry` which is very helpful but for testing purpose, you may need to replace the bean by a mock or a test implementation. + +To bind additional beans, you can still override the well known method `bindToRegistry(Registry registry)` but this method cannot be used to replace a bean created and bound automatically by Camel as it is called too early in the initialization process of Camel. To work around this problem, you can instead bind your beans by overriding the new method `bindToRegistryAfterInjections(Registry registry)` which is called after existing injections and automatic binding have been done. + +In the next example, an instance of a custom bean of type `CustomGreetings` could be created from the value of property `name` and is used to replace the bean of type `Greetings` automatically bound by Camel with the name `myGreetings`. + +[source,java] +---- +class SomeTest extends CamelMainTestSupport { + + @PropertyInject("name") + String name; + + @Override + protected void bindToRegistryAfterInjections(Registry registry) throws Exception { + registry.bind("myGreetings", Greetings.class, new CustomGreetings(name)); + } + + // Rest of the test class +} +---- \ No newline at end of file diff --git a/components/camel-test/camel-test-main-junit5/src/main/java/org/apache/camel/test/main/junit5/CamelMainTestSupport.java b/components/camel-test/camel-test-main-junit5/src/main/java/org/apache/camel/test/main/junit5/CamelMainTestSupport.java new file mode 100644 index 0000000..d05b69b --- /dev/null +++ b/components/camel-test/camel-test-main-junit5/src/main/java/org/apache/camel/test/main/junit5/CamelMainTestSupport.java @@ -0,0 +1,173 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.test.main.junit5; + +import org.apache.camel.CamelContext; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.main.BaseMainSupport; +import org.apache.camel.main.MainConfigurationProperties; +import org.apache.camel.main.MainSupport; +import org.apache.camel.spi.Registry; +import org.apache.camel.test.junit5.CamelTestSupport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The base class of all the test classes that are meant to test a Camel Main application. + */ +public abstract class CamelMainTestSupport extends CamelTestSupport { + + /** + * The logger. + */ + private static final Logger LOG = LoggerFactory.getLogger(CamelMainTestSupport.class); + + /** + * Override this method to be able to configure the Camel for the test like a Camel Main application. + * + * @param configuration the Global configuration for Camel Main. + */ + protected void configure(MainConfigurationProperties configuration) { + // Nothing to do by default + } + + /** + * Override this method to bind custom beans to the Camel {@link Registry} like the method + * {@link #bindToRegistry(Registry)} but after all possible injections and automatic binding have been done which + * for example allows to create the custom beans based on injected objects like properties but also allows to + * replace a bean automatically created and bound by Camel. + * <p> + * In the next example, an instance of a custom bean of type {@code CustomGreetings} could be created from the value + * of property {@code name} and is used to replace the bean of type {@code Greetings} automatically bound by Camel + * with the name <i>myGreetings</i>. + * + * <pre> + * <code> + * + * class ReplaceBeanTest extends CamelMainTestSupport { + * + * @PropertyInject("name") + * String name; + * + * @Override + * protected void bindToRegistryAfterInjections(Registry registry) throws Exception { + * registry.bind("myGreetings", Greetings.class, new CustomGreetings(name)); + * } + * + * // Rest of the test class + * } + * </code> + * </pre> + * + * @param registry the registry in which the custom beans are bound. + * @throws Exception if an error occurs while binding a custom bean. + */ + protected void bindToRegistryAfterInjections(Registry registry) throws Exception { + // Nothing to do by default + } + + /** + * Gives a comma separated list of the property placeholder locations to use for the test. In case a property is + * defined at several property placeholder locations, the value of this property in the first property placeholder + * location according to the order in the list is used. In other words, the value of the properties defined in the + * first location of the property placeholder in the list takes precedence over the value of the properties of the + * following location of the property placeholder and so on. + * <p> + * By default, it tries to get the inferred locations from the method {@link #getPropertyPlaceholderFileName()} in + * case it returns a non {@code null} value otherwise it uses the default property placeholder location + * corresponding to the file {@code application.properties} available from the default package. + * + * @return the location of the property placeholders to use for the test. + */ + protected String getPropertyPlaceholderLocations() { + final String location = getPropertyPlaceholderLocation(); + if (location == null) { + return BaseMainSupport.DEFAULT_PROPERTY_PLACEHOLDER_LOCATION; + } + return location; + } + + /** + * Gives the file name of the property placeholder to use for the test. This method assumes that the property + * placeholder is located in the same package as the test class. In other words, if the test class is + * {@code com.company.SomeTest} and this method has been overridden to return {@code some-app.properties}, then it + * assumes that the actual location of the property placeholder is + * {@code classpath:com/company/some-app.properties}. + * + * @return the file name of the property placeholder located in the same package as the test class. {@code null} by + * default. + */ + protected String getPropertyPlaceholderFileName() { + return null; + } + + @Override + protected void postProcessTest() throws Exception { + LOG.debug("Initialize the camel context as a Camel Main application"); + MainForTest main = new MainForTest(); + configure(main.configure()); + main.setPropertyPlaceholderLocations(getPropertyPlaceholderLocations()); + main.setOverrideProperties(useOverridePropertiesWithPropertiesComponent()); + main.init(context()); + super.postProcessTest(); + } + + @Override + protected void applyCamelPostProcessor() throws Exception { + super.applyCamelPostProcessor(); + bindToRegistryAfterInjections(context.getRegistry()); + } + + /** + * @return {@code null} if {@link #getPropertyPlaceholderFileName()} returns {@code null}, otherwise it will append + * the package of the test class to the file name of the property placeholder. + */ + private String getPropertyPlaceholderLocation() { + final String location = getPropertyPlaceholderFileName(); + if (location == null) { + return null; + } + return String.format("classpath:%s/%s", this.getClass().getPackageName().replace('.', '/'), location); + } + + /** + * An internal implementation of a {@link MainSupport} used to initialize the Camel context the same manner as a + * real Camel Main application. + */ + private static class MainForTest extends MainSupport { + + @Override + protected ProducerTemplate findOrCreateCamelTemplate() { + throw new UnsupportedOperationException(); + } + + @Override + protected CamelContext createCamelContext() { + throw new UnsupportedOperationException(); + } + + /** + * Initialize the given Camel context like a Camel Main application. + * + * @param camelContext the Camel context to initialize. + * @throws Exception if an error occurs while initializing the Camel context. + */ + void init(CamelContext camelContext) throws Exception { + postProcessCamelContext(camelContext); + } + } +} diff --git a/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/AdviceRouteTest.java b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/AdviceRouteTest.java new file mode 100644 index 0000000..398a7d9 --- /dev/null +++ b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/AdviceRouteTest.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.test.main.junit5; + +import org.apache.camel.builder.AdviceWith; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.main.MainConfigurationProperties; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * A test class ensuring that a route can be advised. + */ +class AdviceRouteTest extends CamelMainTestSupport { + + @Override + public boolean isUseAdviceWith() { + return true; + } + + @Override + protected void configure(MainConfigurationProperties configuration) { + // Add the configuration class + configuration.addConfiguration(MyConfiguration.class); + } + + @Test + void shouldAdviceTheRoute() throws Exception { + // Advice the route by replace the from endpoint + AdviceWith.adviceWith(context, "foo", ad -> ad.replaceFromWith("direct:foo")); + + // must start Camel after we are done using advice-with + context.start(); + MockEndpoint mock = context.getEndpoint("mock:out", MockEndpoint.class); + mock.expectedBodiesReceived("Hello Will!"); + String result = template.requestBody("direct:foo", null, String.class); + mock.assertIsSatisfied(); + assertEquals("Hello Will!", result); + } +} diff --git a/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/Greetings.java b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/Greetings.java new file mode 100644 index 0000000..1bd5c52 --- /dev/null +++ b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/Greetings.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.test.main.junit5; + +public class Greetings { + + protected final String name; + + public Greetings(String name) { + this.name = name; + } + + public String sayHello() { + return String.format("Hello %s!", name); + } +} diff --git a/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/MyConfiguration.java b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/MyConfiguration.java new file mode 100644 index 0000000..ba42287 --- /dev/null +++ b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/MyConfiguration.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.test.main.junit5; + +import org.apache.camel.BindToRegistry; +import org.apache.camel.CamelConfiguration; +import org.apache.camel.CamelContext; +import org.apache.camel.PropertyInject; + +/** + * Class to configure the Camel application. + */ +public class MyConfiguration implements CamelConfiguration { + + @BindToRegistry + public Greetings myGreetings(@PropertyInject("name") String name) { + // this will create an instance of this bean and bind it using the name of the method as name (eg myGreetings) + return new Greetings(name); + } + + @Override + public void configure(CamelContext camelContext) { + // this method is optional and can be removed if no additional configuration is needed. + } + +} diff --git a/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/OverridePropertiesTest.java b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/OverridePropertiesTest.java new file mode 100644 index 0000000..b7b7cb2 --- /dev/null +++ b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/OverridePropertiesTest.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.test.main.junit5; + +import java.util.Properties; + +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.main.MainConfigurationProperties; +import org.junit.jupiter.api.Test; + +import static org.apache.camel.util.PropertiesHelper.asProperties; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Test ensuring that the default properties can be overridden. + */ +class OverridePropertiesTest extends CamelMainTestSupport { + + @Override + protected void configure(MainConfigurationProperties configuration) { + // Add the configuration class + configuration.addConfiguration(MyConfiguration.class); + } + + @Override + protected Properties useOverridePropertiesWithPropertiesComponent() { + return asProperties( + "name", "John"); + } + + @Test + void shouldOverrideDefaultProperties() throws Exception { + MockEndpoint mock = context.getEndpoint("mock:out", MockEndpoint.class); + mock.expectedBodiesReceived("Hello John!"); + String result = template.requestBody("direct:in", null, String.class); + mock.assertIsSatisfied(); + assertEquals("Hello John!", result); + } +} diff --git a/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/ReplaceBeanTest.java b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/ReplaceBeanTest.java new file mode 100644 index 0000000..3223268 --- /dev/null +++ b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/ReplaceBeanTest.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.test.main.junit5; + +import org.apache.camel.PropertyInject; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.main.MainConfigurationProperties; +import org.apache.camel.spi.Registry; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * The test class ensuring that an existing bean can be replaced with a bean bound from the test class. + */ +class ReplaceBeanTest extends CamelMainTestSupport { + + @PropertyInject("name") + String name; + + @Override + protected void configure(MainConfigurationProperties configuration) { + // Add the configuration class + configuration.addConfiguration(MyConfiguration.class); + } + + @Override + protected void bindToRegistryAfterInjections(Registry registry) throws Exception { + registry.bind("myGreetings", Greetings.class, new CustomGreetings(name)); + } + + @Test + void shouldReplaceTheBeanWithACustomBean() throws Exception { + MockEndpoint mock = context.getEndpoint("mock:out", MockEndpoint.class); + mock.expectedBodiesReceived("Hi Will!"); + String result = template.requestBody("direct:in", null, String.class); + mock.assertIsSatisfied(); + assertEquals("Hi Will!", result); + } + + static class CustomGreetings extends Greetings { + + public CustomGreetings(String name) { + super(name); + } + + @Override + public String sayHello() { + return String.format("Hi %s!", name); + } + } +} diff --git a/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/ReplaceRouteFromTest.java b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/ReplaceRouteFromTest.java new file mode 100644 index 0000000..d3bb289 --- /dev/null +++ b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/ReplaceRouteFromTest.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.test.main.junit5; + +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.main.MainConfigurationProperties; +import org.apache.camel.test.junit5.CamelTestSupport; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Test class ensuring that a from endpoint can be replaced by leveraging the method + * {@link CamelTestSupport#replaceRouteFromWith(String, String)}. + */ +class ReplaceRouteFromTest extends CamelMainTestSupport { + + @Override + @BeforeEach + public void setUp() throws Exception { + replaceRouteFromWith("foo", "direct:foo"); + super.setUp(); + } + + @Override + protected void configure(MainConfigurationProperties configuration) { + // Add the configuration class + configuration.addConfiguration(MyConfiguration.class); + } + + @Test + void shouldReplaceTheFromEndpoint() throws Exception { + MockEndpoint mock = context.getEndpoint("mock:out", MockEndpoint.class); + mock.expectedBodiesReceived("Hello Will!"); + String result = template.requestBody("direct:foo", null, String.class); + mock.assertIsSatisfied(); + assertEquals("Hello Will!", result); + } +} diff --git a/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/UseSeveralPropertyPlaceholderLocationsTest.java b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/UseSeveralPropertyPlaceholderLocationsTest.java new file mode 100644 index 0000000..783ecb5 --- /dev/null +++ b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/UseSeveralPropertyPlaceholderLocationsTest.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.test.main.junit5; + +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.main.MainConfigurationProperties; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * The test class ensuring that several property placeholder locations can be specified. + */ +class UseSeveralPropertyPlaceholderLocationsTest extends CamelMainTestSupport { + + @Override + protected String getPropertyPlaceholderLocations() { + return "classpath:extra-application.properties,classpath:application.properties"; + } + + @Override + protected void configure(MainConfigurationProperties configuration) { + // Add the configuration class + configuration.addConfiguration(MyConfiguration.class); + } + + @Test + void shouldApplyAllPropertyPlaceholderLocations() throws Exception { + MockEndpoint mock = context.getEndpoint("mock:out", MockEndpoint.class); + mock.expectedBodiesReceived("Hello Jack!"); + String result = template.requestBody("direct:in", null, String.class); + mock.assertIsSatisfied(); + assertEquals("Hello Jack!", result); + } +} diff --git a/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/custom/LoadCustomConfigurationTest.java b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/custom/LoadCustomConfigurationTest.java new file mode 100644 index 0000000..eaae13b --- /dev/null +++ b/components/camel-test/camel-test-main-junit5/src/test/java/org/apache/camel/test/main/junit5/custom/LoadCustomConfigurationTest.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.test.main.junit5.custom; + +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.main.MainConfigurationProperties; +import org.apache.camel.test.main.junit5.CamelMainTestSupport; +import org.apache.camel.test.main.junit5.MyConfiguration; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * The test class ensuring that a custom property placeholder can be specified with the name of the file located in the + * same package. + */ +class LoadCustomConfigurationTest extends CamelMainTestSupport { + + @Override + protected String getPropertyPlaceholderFileName() { + return "custom-application.properties"; + } + + @Override + protected void configure(MainConfigurationProperties configuration) { + // Add the configuration class + configuration.addConfiguration(MyConfiguration.class); + // Add all the XML routes + configuration.withRoutesIncludePattern("routes/*.xml"); + } + + @Test + void shouldFindCustomConfiguration() throws Exception { + MockEndpoint mock = context.getEndpoint("mock:out", MockEndpoint.class); + mock.expectedBodiesReceived("Hello John!"); + String result = template.requestBody("direct:in", null, String.class); + mock.assertIsSatisfied(); + assertEquals("Hello John!", result); + } +} diff --git a/components/camel-test/camel-test-main-junit5/src/test/resources/application.properties b/components/camel-test/camel-test-main-junit5/src/test/resources/application.properties new file mode 100644 index 0000000..30b1d92 --- /dev/null +++ b/components/camel-test/camel-test-main-junit5/src/test/resources/application.properties @@ -0,0 +1,23 @@ +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- + +# load XML routes +camel.main.routes-include-pattern = routes/*.xml + +# application properties +name = Will + diff --git a/components/camel-test/camel-test-main-junit5/src/test/resources/extra-application.properties b/components/camel-test/camel-test-main-junit5/src/test/resources/extra-application.properties new file mode 100644 index 0000000..4d039ac --- /dev/null +++ b/components/camel-test/camel-test-main-junit5/src/test/resources/extra-application.properties @@ -0,0 +1,20 @@ +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- + +# application properties +name = Jack + diff --git a/components/camel-test/camel-test-main-junit5/src/test/resources/log4j2.properties b/components/camel-test/camel-test-main-junit5/src/test/resources/log4j2.properties new file mode 100644 index 0000000..53994e6 --- /dev/null +++ b/components/camel-test/camel-test-main-junit5/src/test/resources/log4j2.properties @@ -0,0 +1,30 @@ +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- + +appender.file.type = File +appender.file.name = file +appender.file.fileName = target/camel-test.log +appender.file.layout.type = PatternLayout +appender.file.layout.pattern = %d %-5p %c{1} - %m %n +appender.out.type = Console +appender.out.name = out +appender.out.layout.type = PatternLayout +appender.out.layout.pattern = [%30.30t] %-30.30c{1} %-5p %m%n +logger.springframework.name = org.springframework +logger.springframework.level = WARN +rootLogger.level = INFO +rootLogger.appenderRef.file.ref = file diff --git a/components/camel-test/camel-test-main-junit5/src/test/resources/org/apache/camel/test/main/junit5/custom/custom-application.properties b/components/camel-test/camel-test-main-junit5/src/test/resources/org/apache/camel/test/main/junit5/custom/custom-application.properties new file mode 100644 index 0000000..4d0c253 --- /dev/null +++ b/components/camel-test/camel-test-main-junit5/src/test/resources/org/apache/camel/test/main/junit5/custom/custom-application.properties @@ -0,0 +1,20 @@ +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- + +# application properties +name = John + diff --git a/components/camel-test/camel-test-main-junit5/src/test/resources/routes/my-route.xml b/components/camel-test/camel-test-main-junit5/src/test/resources/routes/my-route.xml new file mode 100644 index 0000000..e615854 --- /dev/null +++ b/components/camel-test/camel-test-main-junit5/src/test/resources/routes/my-route.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<routes id="camel" xmlns="http://camel.apache.org/schema/spring"> + <route id="foo"> + <from uri="direct:in"/> + <bean ref="myGreetings"/> + <to uri="mock:out"/> + </route> +</routes> diff --git a/components/camel-test/pom.xml b/components/camel-test/pom.xml index 8595e4b..9079288 100644 --- a/components/camel-test/pom.xml +++ b/components/camel-test/pom.xml @@ -39,6 +39,7 @@ <module>camel-test-spring</module> <module>camel-test-junit5</module> <module>camel-test-spring-junit5</module> + <module>camel-test-main-junit5</module> </modules> </project> diff --git a/docs/components/modules/others/examples/json/test-main-junit5.json b/docs/components/modules/others/examples/json/test-main-junit5.json new file mode 120000 index 0000000..e1b7719 --- /dev/null +++ b/docs/components/modules/others/examples/json/test-main-junit5.json @@ -0,0 +1 @@ +../../../../../../components/camel-test/camel-test-main-junit5/src/generated/resources/test-main-junit5.json \ No newline at end of file diff --git a/docs/components/modules/others/nav.adoc b/docs/components/modules/others/nav.adoc index 5e27fb6..96a4f6a 100644 --- a/docs/components/modules/others/nav.adoc +++ b/docs/components/modules/others/nav.adoc @@ -60,6 +60,7 @@ ** xref:test-cdi.adoc[Test CDI] ** xref:test-cdi-junit5.adoc[Test CDI JUnit5] ** xref:test-junit5.adoc[Test JUnit5] +** xref:test-main-junit5.adoc[Test Main JUnit5] ** xref:test-spring.adoc[Test Spring] ** xref:test-spring-junit5.adoc[Test Spring JUnit5] ** xref:threadpoolfactory-vertx.adoc[ThreadPoolFactory Vert.x] diff --git a/docs/components/modules/others/pages/test-main-junit5.adoc b/docs/components/modules/others/pages/test-main-junit5.adoc new file mode 120000 index 0000000..6bbfe31 --- /dev/null +++ b/docs/components/modules/others/pages/test-main-junit5.adoc @@ -0,0 +1 @@ +../../../../../components/camel-test/camel-test-main-junit5/src/main/docs/test-main-junit5.adoc \ No newline at end of file diff --git a/docs/user-manual/modules/ROOT/pages/testing.adoc b/docs/user-manual/modules/ROOT/pages/testing.adoc index c21984c..3b5105b 100644 --- a/docs/user-manual/modules/ROOT/pages/testing.adoc +++ b/docs/user-manual/modules/ROOT/pages/testing.adoc @@ -26,6 +26,9 @@ class for all your configuration and routing without. |xref:components:others:test-junit5.adoc[camel-test-junit5] |*JUnit 5*: Is a standalone Java library letting you easily create Camel test cases using a single Java class for all your configuration and routing without. +// Un-comment me once 3.16.x is out -- START +//|xref:components:others:test-main-junit5.adoc[camel-test-main-junit5] | *JUnit 5*: Used for testing Camel in Camel Main mode +// Un-comment me once 3.16.x is out -- STOP |xref:components:others:test-spring.adoc[camel-test-spring] | *JUnit 4 (deprecated)*: Used for testing Camel with Spring / Spring Boot |xref:components:others:test-spring-junit5.adoc[camel-test-spring-junit5] | *JUnit 5*: Used for testing Camel with Spring / Spring Boot diff --git a/parent/pom.xml b/parent/pom.xml index bf1947c..14c03e1 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -2573,6 +2573,11 @@ </dependency> <dependency> <groupId>org.apache.camel</groupId> + <artifactId>camel-test-main-junit5</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> <artifactId>camel-test-parent</artifactId> <version>${project.version}</version> </dependency>