How can I make fun of the presence of a properties file in the classpath?

This is certainly a common problem. I have a properties file, for example my-settings.properties , which is read by the application class. When I write a test class, it needs to test different scenarios of things that may be present in my-settings.properties in order to ensure maximum code coverage (for example, an 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 cool if there was only some kind of annotation

@MockFileOnClassPath(use = "my-settings-basic.properties", insteadOf = "my-settings.properties")

Then I could just have some my-settings-XXX.properties files in my /src/test/resources and just annotate the correct text for each testing method. But I can not find anything like it. I am using JUnit 4.12.

I can think of some rough decisions:

  • Before each test, find the file in the file system, copy it using the file system I / O, and then delete it again after the test. But this is awkward and requires a lot of redundancy. Not to mention that I'm not even sure if the classpath directory will be writable.
  • Use a fake framework to mock getResource . I don’t know how I would do it, especially since there are a million different ways to get the file ( this.getClass().getResourceAsStream(...) , MyClass.class.getResourceAsStream(...) , ClassLoader.getSystemClassLoader().getResourceAsStream(...) etc.)

I just think this should be a common problem, and maybe there is already a solution in JUnit, Mockito, PowerMock, EasyMock, or something like that?

EDIT . Someone pointed out that this question is a duplicate. Specifying your own log4j.properties file for all JUnit tests running with Eclipse but it is not. This question is the desire to have a different properties file between the main and test calls. For me, I want to have a different properties file between a test call and another test call.

+5
source share
2 answers

I believe that whenever it comes to files, it is best to introduce the concept of Resource .

eg:

 public interface Resource { String getName(); InputStream getStream(); } 

Then you can pass the resource through 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 perhaps a FileResource or URLResource , etc., but in your tests you could have a StringResource , etc.

Please note that if you use spring, you already have an implementation of this concept. More here

+1
source

You can change the Service class to accept the resource file name, and then use name to load the resource .

 public class MyService { public MyService(String resourceFileName){ //and load it into Properties getResourceAsStream(resourceFileName); } } 
+2
source

Source: https://habr.com/ru/post/1232467/


All Articles