This surely is a common problem. I have a properties file like my-settings.properties
which is read by an application class. When I write a test class, it needs to test different scenarios of things that could be present in my-settings.properties
in order to ensure maximum code coverage (e.g. empty properties file, basic properties file etc). But I can only have one my-settings.properties
in my src/test/resources
.
What would be really great is if there was just some annotation
@MockFileOnClassPath(use = "my-settings-basic.properties", insteadOf = "my-settings.properties")
Then I could just have multiple my-settings-XXX.properties
files in my /src/test/resources
and just annotated the correct one on each test method. But I can't find anything like this. I'm using JUnit 4.12.
I can think of a couple of crude solutions:
getResource
. No idea how I would even do that, especially as there are a million different ways to get the file (this.getClass().getResourceAsStream(...)
, MyClass.class.getResourceAsStream(...)
, ClassLoader.getSystemClassLoader().getResourceAsStream(...)
etc.)I just think this must be a common problem and maybe there is already a solution in JUnit, Mockito, PowerMock, EasyMock or something like that?
EDIT: Someone has specified that this question is a duplicate of Specifying a custom log4j.properties file for all of JUnit tests run from Eclipse but it isn't. That question is about wanting to have a different properties file between the main and test invocations. For me I want to have a different properties file between a test invocation and another test invocation.
I find that whenever dealing with files, it's best to introduce the concept of a Resource
.
eg:
public interface Resource {
String getName();
InputStream getStream();
}
Then you can pass the resource in via dependency injection:
public class MyService {
private final Properties properties;
public class MyService(Resource propFile) {
this.properties = new Properties();
this.properties.load(propFile.getStream());
}
...
}
Then, in your production code you can use a ClasspathResource
or maybe a FileResource
or URLResource
etc but in your tests you could have a StringResource
etc.
Note, if you use spring you already have an implenentation of this concept. More details here
You can change your Service
class to accept the name of the resource
file, then then use that name
to load the resource
.
public class MyService {
public MyService(String resourceFileName){
//and load it into Properties getResourceAsStream(resourceFileName);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With