Spring Boot multi-module unit test for service - java

I have multi-module spring boot micro-service architecture like this:
<modules>
<module>commons</module>
<module>dao</module>
<module>service</module>
<module>api</module>
</modules>
Here I have put my Application.java in API module, which is having all the configuration. Now I want to test my service class methods but I am not able to add the configuration.
Do I need to write separate configuration or is there any other solution for this?

Related

How to use Spring Boot with Spring Data in a module without an actual Spring Boot application?

I have to write a small project, which is not runnable by itself, but it is used by some other ("main") project as dependency to do some database operations and some simple business logic. So there will be no actual main class in my project, only some API, which will be used by the main project. Now I was wondering, if it is possible, to use Spring Boot with Spring Data JPA in my small project for Database operations. So there will be no #SpringBootApplication annotated class. (And the main project is also not a Spring Boot application)
So I actually modified my pom.xml by adding this:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
(...)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Also I added an application.properties file in resources folder:
spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.show_sql=false
spring.jpa.properties.hibernate.format_sql=false
And finally, I added a simple config file:
#Configuration
#ComponentScan
#EnableJpaRepositories("package-of-the-JPA-repositories")
//#EnableAutoConfiguration
#EntityScan("package-of-the-entities")
#PropertySource("classpath:/application.properties")
public class SpringConfig {
}
Well, this configuration done, I tried to run the main project, but it sais, it cannot find the entityManagerFactory bean. As I understood, Spring Boot should generate this bean from the specified properties. So my question would be: 1) Is the thing I am tring to do generally possible? Means, is it possible to use Spring Boot without having an #SpringBootApplication annotated class? Or should I rather get rid of Spring Boot and use only Spring Data and Hibernate? And if it is possible, what am I possibly doing wrong? Any ideas?

How to know if a project is spring boot or not

I went through a project structure in STS where I could see a MVC pattern where controller, service,Dao , entity classes were there. But looking at pom.xml got to know that it is a web application project. But how to confirm that it is not a spring boot application..?
I m new to spring boot. All I found is there were no starter dependencies in pom.xml or any dependency has word "boot" & there was not a main method where a spring boot project starts.
So my question is which particular dependency/ parameters differentiates spring boot application from a non spring boot application ?
In general in the first part of the pom.xml you can see this tag:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath />
<!-- lookup parent from repository -->
</parent>
Check the pom.xml. see if it includes the spring boot dependency or any other Spring boot dependency flavors like Spring-boot-starter, spring-boot-autoconfigure,spring-boot-web etc....
Basically anything with group ID
"org.springframework.boot"
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
Additionally also look for the #SpringBootApplication annotation on top of the main class.
If you're running a Gradle project, you might see something like this inside of one of your build.gradle (or [projectName].gradle) files.
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
Or maybe
apply plugin: 'org.springframework.boot'
The above advice to search globally for org.springframework.boot is sound, just wanted to stress there might not be a pom.xml (or any .xml) files present.

Activate profiles for spring boot test using application.properties file

I have been using Spring Boot and TestNG for my test framework and so far my tests were configured to use only one default application.properties file which is under src/main/resource. Now I want to configure them for different environments - ci/stage etc. I have used spring documentation to activate the profiles from pom.xml file.
<profiles>
<profile>
<id>ci</id>
<properties>
<activeProfile>ci</activeProfile>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
</profiles>
I have for two properties files under src/main/resources - application.properties and application-ci.properties. (The is the naming convention suggested by spring documentation. application-{activatedprofile}.properties).
The application.properties have got a placeholder -
spring.profiles.active=#activeProfile#
The #activeProfile# will get replaced with the value of activeProfile in the pom.xml file.And uptil that it is working.
In my #Configuration class I have a annotation as below and I am expecting that the ${spring.profiles.active} value gets replaced with value - ci.
#PropertySource("classpath:application-${spring.profiles.active}.properties")
I am getting following error:
java.lang.IllegalArgumentException: Could not resolve placeholder
'spring.profiles.active' in value
"classpath:application-${spring.profiles.active}.properties"
I am using maven and testng to run my project. I am doing something incorrect let me know how can I resolve it.
First of all, the maven profile is not the same as the spring profile. In the code snippet provided you are setting the maven profile, not the spring profile.
To pass a specific spring profile during your test phase you can use the surefire plugin. In the code snippet below you would be passing in the system property spring.profiles.active as ci. This is equivalent to setting the value in your application.properties file.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<systemPropertyVariables>
<spring.profiles.active>ci</spring.profiles.active>
</systemPropertyVariables>
</configuration>
</plugin>
Secondly, spring will automatically load the property sources based on the active spring profile. In your example, spring will first load application.properties then it will apply application-ci.properties on top of it. As a result
#PropertySource("classpath:application-${spring.profiles.active}.properties")
is not needed.
If you have a configuration class that is specific to an active profile then you can add #ActiveProfiles("ci") to your configuration class and it will only use that class when the profile ci is active.
Lastly, you do not need the property spring.profiles.active=#activeProfile# in your application.properties files as this be passed in from the surefire plugin in maven.

Multiple Spring profiles and Maven profiles in one war

I got parser Spring Batch sheduled jobs. I got many jobs and here are just two of them:
#Profile("eodT0")
#EnableBatchProcessing
#Configuration
public class JobConfigurationEodT0 { ... }
#Profile("eodRepo")
#EnableBatchProcessing
#Configuration
public class JobConfigurationEodRepo { ... }
My application.yml config:
spring:
profiles.active: #activatedProperties#
And pom.xml:
Some profiles from big list of them:
<profiles>
<profile>
<id>eodT0</id>
<properties>
<activatedProperties>eodT0</activatedProperties>
</properties>
</profile>
<profile>
<id>eodRepo</id>
<properties>
<activatedProperties>eodRepo</activatedProperties>
</properties>
</profile>
</profiles>
I want it to be like
spring:
profiles.active: eodT0, eodRepo instead of #activatedProperties#
If I check more than one maven profile only one will work. I need to check profiles depending on what jobs I want to do to make them all active to make war and put it on server. How is it to be done?
Why not pass it as a system property.
mvn package -DactivatedProperties=eodT0,eodT1

Any way to specify module properties from an orchestrator (non-parent) pom?

I have a multi-module maven 3 project, in which I have an orchestrator/build pom whose sole job is to run the maven build. Each module already has its parent pom, none of which are this orchestrator pom.
Is there any way from within the orchestrator pom to set/specify property values that would be used by the modules? Since the modules do not inherit the orchestrator pom, they know nothing of any property values set/specified within it (ex: ${buildEngine} or ${cluster}).
For ex:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.sbic</groupId>
<artifactId>builder</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Orchestrator Pom</name>
<properties>
<buildEngine>Geronimo</buildEngine>
<cluster>peanuts</cluster>
</properties>
<modules>
<!-- Supert POM Component Versionning -->
<module>SbiComMavenCommon</module>
<!-- Projects -->
<module>../AlertServices</module>
<module>../Configuration</module>
<module>../Core</module>
</modules>
</project>
In order to build my project, I simply call mvn package on this builder pom.
What I am looking for is an ability to specify properties in this builder pom that would then be used by the modules, WITHOUT requiring the modules to have this pom in its parent tree.
For example, something that would accomplish the following (obviously not valid pom syntax):
<module>
../Core
<properties>
<name>SomeValue</name>
<server>192.168.1.2</server>
</properties>
</module>
There is no direct way to do it with Maven which I'm aware of. But, there is a workaround - use properties:set-system-properties from Properties Maven plugin
Of course, caveats apply, as for any global shared mutable state. For example, the module parent/child relationships are not respected. Though it looks like you want it anyway.

Categories

Resources