Mock a config file - java

I'm writing tests for an app that refers to a hardcoded filename "classpath:config.properties". It isn't possible to change this name. Is there any way to test this app with different configs? i.e. different tests supply different configs at runtime?
This is an odd requirement, but I'd deeply appreciate any inputs

Here is another question that might help you:
Dynamically loading properties file using Spring
Or you can always overwrite the properties file using the Java IO libraries.

It's all about classpath - what jars are in classpath and how you organize your project structure.
User maven so that resources from 'src/test/resources' are loaded before 'src/main/resources'. But generally the best way is to separate application-specific config resources from application code.
Alternatively, you can split the project with config resources into 3 or 4 projects:
project with code
project with config resources, added to app classpath, but not to test classpath
project with test resources, added to test classpath, but not to the app classpath
optionally, you can move JUnit test code to separate project

If you load your configuration from classpath:config.properties then these properties reside in src/main/resources folder.
When you run tests you can put your mock configuration in src/test/resources and it will "override" main configuration.

Related

JUnit5: Where is the root of #CsvFileSource defined and can that definition be changed to refer to a different directory?

I started a project as a maven-quickstart and added JUNIT5.
There was no 'resources' folder anywhere. It builds using a pom.xml and up to "package" goal.
Some time after, one of the testers wanted to add a test that reads from a CSV file.
He had some trouble setting up and I recalled from just memory that it will look in test/resources.
We are all fine now but I just can't stop wondering: Is 'test/resources' hard-coded into JUnit? Or is it somehow derived from the project archetype?
Is there a way to edit this reference in the project settings, vm settings or maybe in the very test method?
From https://junit.org/junit5/docs/5.3.0/api/org/junit/jupiter/params/provider/CsvFileSource.html
used to load comma-separated value (CSV) files from one or more classpath resources.
The way to load resources with this annotation (if they are not on the classpath) is to put them on the classpath.
So, to answer your question - yes you can change this setting by changing the classpath.
How you do that depends on what you are using to build, e.g.:
For java, you use java -cp ..., maven, gradle, ant all have different ways and since you have not posted a specific question we can't give a specific answer.
EDIT - Since you're using Maven - create a src/test/resources (or src/main/resources) and unless you're overriding the defaults Maven will automatically make those part of the test classpath (and classpath, respictively). Put your file in src/test/resources and it should work.

Is it possible to add files to classpath for testing and how

My project is Java & Maven based. I have a properties file under src/main/resources so when I try to do MyClass.class.getClassLoader().getResourceAsStream(propertyFileName) everything loads fine. My understanding is that as long as I have the property file in classpath it should get picked up.
My goal here is to write a unit test where I can test this out. I know in Spring framework there are classpath load apis that let you pick up any file and add it to the classpath during testing. I am not using Spring here so what is the best way for me to create a properties file in memory, and it to classpath for the duration of the test?
Pseudo steps:
begin method
create file in memory with properties
add file to classpath
print properties
end method
I am using Eclipse. Thanks in advance.
Update - I am trying to add a file to classpath on the fly because a jar may be run from command line or a second file in the resources might override the default props file

Configure log4j.properties file location when packing to jar

I have a concern that where do we have to put log4j.properties file when packaging to jar file by using maven.what is the best practice here.
General recommendation
Put it into src/main/resources. You may want to define a more verbose log4j configuration in src/test/resources, if you do use junit tests.
See maven standard directory layout.
Setting a new configuration for specific executions
If you want to create an executable jar with a main method, you can ship a default configuration in src/main/resources and still provide an overriding log configuration when starting your jvm, using this jvm parameter: -Dlog4j.configuration=file:"<FILE_PATH>".
Building for multiple environments
You can also create multiple subfolders in your resource configuration and have the maven resource plugin copy the correct log4j.xml to the destination via maven profiles.

Where should application.properties file get stored?

In a java project where does the application.properties file commonly get stored?
I store my application properties in src.main.resources. Resources package is quite self-explanatory and property files can be easily found there for everyone who looks at this project for the first time. Resouces are stored in main package in case you need different configuration for your tests, therefore I have also src.test.resources package.
In a JAVA project you can keep the properties files wherever you want, as long as you can find them during runtime.
Take a look at this question for more details: Loading a properties file from Java package
For a MAVEN project:
You can of course override this, but normally properties files in maven projects are kept in specific places:
Configuration used during runtime is kept in src/main/resources.
Configuration used during tests is kept in src/test/resources.

What's the ideal way to configure an Eclipse Web Project to test Spring/JPA

I recently used eclipse (myeclipse actually) to create a new Web Project via the new->web project wizard. The default directory structure for the project looks as follows:
src
WebRoot
WebRoot/META-INF
WebRoot/META-INF/MANIFEST.MF
WebRoot/WEB-INF
WebRoot/WEB-INF/lib
WebRoot/WEB-INF/classes (not visible via the Package/Project Explorer)
WebRoot/WEB-INF/web.xml
For jpa I added:
WebRoot/META-INF/persistence.xml
For spring I added:
WebRoot/META-INF/spring/spring-master.xml
When trying to run a very basic junit test to load the spring context and hibernate entity manager I was running into classpath problems. Initally to get around the first class path problem I encountered I added WebRoot/META-INF/spring to the junit->Run Configurations classpath when Spring couldn't find my spring configuration files.
But then I ran into another classpath error when jpa couldn't find my entity bean definition. Reading this article (dated 2007) it states that META-INF/persistence.xml should be contained within WEB-INF/classes because JPA searches for entity bean class files in the parent directory of META-INF/persistence.xml
When I copied META-INF (via Windows Explorer since eclipse is hiding the classes directory) and all its contents into WEB-INF/classes my classpath errors went away (as well as the need to monkey with the junit run configuration to remedy the previous problem of spring not knowing where my spring config file is located turns out I still need to add the spring folder to the junit classpath option).
But now I have configuration files in a folder which does not show in Eclipse's Package/Project Explorer.
What is the best way to setup Eclipse for this situation? Tell it to show the classes folder somehow? Why does Eclipse create META-INF as a sibling to WEB-INF for web projects?
Is there a way to inform JPA to look for entity classes somewhere other than the default?
Thanks for any input!
You should know that eclipse mixes the compiled classes and resource from src (and any other source code directory) in the <WebRoot>/WEB-INF/classes directory.
So one way to access the same file in Test and Webapp (for example META-INF/persistence.xml) is to put it in src/META-INF/persistence.xml. Then it is available in <WebRoot>/WEB-INF/classes/META-INF/persistence.xml for the web app, and in <classpath>/META-INF/persistence.xml for EVERY application or test.
So my recommendation is to put all the stuff that is addressed via classpath (persistence.xml, spring.xml) in a source directory, and let eclipse do the rest. - If you specify the location of a resource via classpath, then it should work the same way for webapp, test, app.
BTW: eclipse can create many source code directories, you can use one for the normal application classes, one for the class path relevant resource and one for the test classes.

Categories