Any way to create a permanent JUnit config. on IntelliJ? - java

I try to test my spring boot application via JUnit 5.
The test methods need some environment variables. Even I put them on the list, each test method creates a new JUnit config so I have to put them again.
I saw the document on JetBrains.
I can not save the JUnit config. because each config. depends on the method.
Is there any way to create a permanent JUnit config. on IntelliJ?

You may edit the Junit run configuration in the "Run configuration templates for new projects":

This is a bad idea. Setting up your environment variables in something like IntelliJ will make this unportable or unrunnable in a Jenkins environment.
Because you're using Spring Boot, you have more flexibility than you realize. Rework your code so that the environment variables can be injected in through application properties. Then, you can add the application properties to your test through the #SpringBootTest annotation.

Related

How to use environment variables on a Spring Boot and Gradle application?

I explain my problem;
I have a web app developed using Vue.js and Spring Boot, this application working a PDF sheet and saves the file that is generated by Java, I use two lines of code to separate my development part from the production part (I leave you the 2 lines of code like this you understand the concept well)
FileReader leggoFile = new FileReader(System.getProperty("user.dir") + "/temp/webapps/foolder/foolder/file.pdf");
// FileReader leggoFile = new FileReader(System.getProperty("catalina.base") + "/temp/webapps/foolder/foolder/file.pdf");
This whole application is built using the "bootWar gradle plugin" which returns me a .war which I will then upload to a Tomcat server;
My goal is this:
I would like to set a single environment variable so that if I want to build the project I don't have to comment/uncomment that line for example:
FileReader leggoFile = new FileReader({{variableEnvironment}} + "/temp/webapps/foolder/foolder/file.pdf")
my question is this:
How dp Gradle and Spring Boot handle environments? Is there a way to separate environments? Is this possible or should I start thinking differently?
I tried to search on something but unfortunately I was tied to the problem that I don't understand how the .war file is generated through the BootWar Gradle plugin, also searching on the internet I understood that environment Gradle and environment Spring are two separate things but in general even if I know the line of code is wrong in the beginning my question is always the same:
How are environment variables handled in Spring and Gradle?
With Spring Boot, you can add properties to your application by adding an file named application.yaml to your resources folder (src/resources/). In addition you can add properties through application-{profile}.yaml to add properties only for given Spring profiles. For instance application-test.yaml would only be read if "test" is an active profile. When booting up the application, Spring will first read application.yaml, then any profile-specific YAML-files, such that any overlapping properties are replaced.
There are several approaches to injecting the property. A simple solution is to add a field to your component annotated with #Value("${PATH}) and replace PATH with the property's path in the YAML.

Externalizing Run configurations for Grails app

Is there a way to externalize the run config for per environment configurations with Grails 3 applications?
I am aware that there are run config arguments that allow one to run their application under a dev, prod, test, etc environment, but I was wondering if there is a variable, for example "grails.env" that I can change in a properties, YAML, config, or other file that can be read at run time that will do this for me.
This is just to avoid confusion between the application being tested and run in one setting/environment(physical environment like my local machine), then being given to another individual or team to run elsewhere.
The goal is to configure or set this variable so the run team/individual wont need to know or change the run commands.
Im aware of how to configure the environment with the command line, and within intelliJ and Eclipse. I'm wondering if there is a way to default this in perhaps a file that is read instead.
Thanks
I'm not to sure what is confusing you here but let me try and see if I can point you in the right direction
From the documentation here: http://docs.grails.org/latest/guide/conf.html#environments your application can be delivered as a package war file to the target user to have tested, and the war file can be created with any of of the environment configurations
grails test war
Since the command is can be run in the console, you could run with system properties like this:
grails $ENVIRONMENT war
Hope this helps
Update 2
By default the grails run-app runs with the dev environment, but you can force an environment by doing
grails $env run-app
If you want some default configurations to be run when you use the run-app command, then you should make sure that configuration is not in the environment block in either application.yml or application.groovy
Example of configuration in the environment block:
-----------------------------------------------------
environment{
development{
appConfig{
ishybrid = true
}
}
}
Example of configuration not in any environment block:
-------------------------------------------------------
appConfig{
ishybrid = true
}
environment{
development{
//other configs
}
}
So basically depending on what you exclude from the environment block configuration is what will be configured as the default configuration for your application to run.
Hope this helps better?

Initialising a database before Spring Boot test

I'm using JUnit to test my application and everything works fine as long as the database has been initialised before the testing (using gradle bootRun to run as a web-app). However, if the database is empty, the application does not seem to initialise any models or entities before testing. Is there a way I'm supposed to do this? I made an assumption that the ApplicationRunner class will be ran before the test and initalise the entities. Is there a way to do this or am I using the wrong approach?
This is how my application.properties file is looking like:
server.port=8090
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=123456
server.ssl.key-password 123456
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.hibernate.ddl-auto=create
spring.jpa.hibernate.naming-strategy:org.hibernate.cfg.ImprovedNamingStrategy
application.logger.org.springframework=INFO
My database is stored in /src/main/java/application/persistence/DbConfig.java using a DriverManagerDataSource connection. And I have setup ApplicationRunner to run add a few rows to the db upon starting.
edit:
I should also add that these are the annotations I'm using on the JUnit test file:
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration(classes={
AdeyTrackApplication.class,
SecurityConfig.class,
WebConfig.class,
AuthorizationController.class
})
There are various options if you do not want to execute that explicitly from #Before JUnit hook.
Use Spring Boot's JDBC initialization feature, where you would place schema.sql or data.sql into src/test/resources folder, so that it would be picked up only during testing.
Use Spring's #Sql annotation
You can use #Sql annotaion for populate your DB, for example^
#Sql(scripts = "classpath:db/populateDB.sql")
The above answers all use the .sql schema loading technique where I'd have to have a .sql schema for tests. I didn't want to do it that way as my schema would be expanding and I'd rather not go through the hassle of adding entries to the schema as my tests expand.
As I'm using Spring Boot, I came across this annotation which seems to solve the issue by first running bootRun and then running the tests.
In my test annotations I replaced the #ContextConfigurations with #SpringApplicationConfiguration and left all the classes to be the same. This seemed to solve the issue. So now the test task invokes bootRun to load the classes and then runs the tests.
See #SpringApplicationConfiguration
Hop this helps anyone facing the same issue.

How to get runtime values through (Maven, TestNG, Java)

I am just started to automate my Web service project with Java. I need to run it in Jenkins so I built the project with TestNG framework and Maven. I am able to run some automated test suite with Jenkins without any issues.
Now I have problem like, I need to get the user input at runtime (say HostName, UserName, Password, etc) and then the test suite should run accordingly.
The problem I am facing like, while entering the input in the console the cursor is not returning back to the program and it simple going to ideal state.
PFA screenshots:
Test case running as Maven build
Test case running as TestNG
Making your tests interactive is absolutely bad approach - the build is just not reproducible at all, makes other people know what parameters are expected and so on.
If your test case need to take parameters at runtime (or more accurately, they need to be set before maven build is started) you have several options.
Option #1. Properties file and maven resource processing.
Idea is just to have a properties file in your project and tell maven to resolve variable
values there. Example:
Pom.xml:
<resources>
<resource>
<directory>src/test/resources/data</directory>
<filtering>true</filtering>
</resource>
</resources>
/src/test/resources/data/myproperties.properties:
myVar = ${myVar}
Then run maven build as:
mvn -DmyVar=value clean install
You can use not only properties files, but any other file types (for example XML).
Hint: you can use maven-enforcer-plugin to force user to enter -DmyVar, this plugin will fail the build if all required properties are not set.
Option #2. Properties file and Spring DI.
Idea is almost same as above, but Spring is used to inject all necessary stuff to test class. Something like:
#Component
public class MyTest
{
#Value(${myProperty})
private String myValue;
// ... Test methods which can use myValue ...
}
See this answer for full example of possible Spring configuration.
Btw, your test is the a unit test, but integration test - in case if it involves deploying of your web service or something else like this. Therefore, it would be wise to split unit tests (maven-surefire-plugin) and integration tests (maven-failsafe-plugin).

Setting OSGi storage directoy (org.osgi.framework.storage) does not work in Maven triggered JUnit test

In my code I start multiple OSGi frameworks using EquinoxFactory. By setting the property "org.osgi.framework.storage" to "#user.home/osgi-frameworks/framework-x", where x is different for every framework, each framework uses a different directory:
frameworkProperties.put("osgi.clean", "true");
frameworkProperties.put("osgi.console", "true");
frameworkProperties.put("org.osgi.framework.storage",
"#user.home/osgi-frameworks/osgi-framework-"
+ numberOfFramework);
framework = new EquinoxFactory().newFramework(frameworkProperties)
This works perfectly when running the actual application. Also the JUnit tests in the IDE run without any problems.
However, when I start the Maven build for my project, the JUnit tests fail since all frameworks use the same directory ("osgi-frameworks/framework-0").
I added logging to the application to check whether the property "org.osgi.framework.storage" does really have different value in the OSGi property map. Everything looks fine in the log, but when checking the file space, only one directory has been created.
Since I would like to include the application in Jenkins, I would rather not skip the tests.
Has anyone an idea what could be wrong? Do I have to set other parameters for the framework? Is there any considerable difference between Junit in the IDE and in Maven?

Categories