Search code examples
javaunit-testingtestingowner

Testing with java owner aeonbits


I've been using java OWNER for property based configuration.

I've create a static method

public static final ApplicationConfiguration config = ConfigFactory.create(ApplicationConfiguration.class,
        System.getProperties(), System.getenv());

and I import the class everywhere I need conf.

Needless to say, unit testing is a PITA. I couldn't find a good way of override the values in the configuration.

I would like to avoid passing the config as a dependency in every class. It adds a lot of verbosity and it doesn't make sense from a design point of view. Same applies for calling the config factory in every class

ApplicationConfiguration config = ConfigFactory.create(ApplicationConfiguration.class,
        System.getProperties(), System.getenv());

Have you got any suggestion? is there a best practice?


Solution

  • Two things:

    1. You can create a class that provides the properties and all users use it:

      public class PropertiesAccessor {
      
         private static MyConfiguration mMyConfig = ConfigFactory.create(MyConfiguration.class);
      
         private PropertiesAccessor() 
            // No need to allow instantiation of this class
         }
      
         /**
          * Get properties for this application
          *
          * @return Properties
          */
         public static MyConfiguration getProperties() {
            return mMyConfig;
         }
      
         // for unit testing
         @VisibleForTesting
         public static void setProperties(MyConfiguration config) {
            mMyConfig = config;
         }
      }
      

      Now, everywhere you need a property, you can use this static method

      PropertiesAccessor.getProperties()
      
    2. Notice that there is a method for testing, setProperties(). There are different ways to use this method. You can create a test property file, load it in, then call the setProperties() method. I like to have a utility method like this:

      public static void initProperties(String fileName) {    
      
         Properties testProperties = new Properties();    
      
         File file = new File(fileName);
         FileInputStream stream = null;   
         try {    
            stream = new FileInputStream(file);   
            testProperties.load(stream);  
         } catch (IOException e) {    
            // Log or whatever you want to do
         } finally {  
            if (stream != null) {
            try { 
               stream.close();    
         } catch (IOException e) {    
           // Log or whatever you want to do; 
         }    
      
         MyConfiguration config = ConfigFactory.create(MyConfiguration.class, testProperties);    
         PropertiesAccessor.setProperties(config);
      }
      

      Then, you can have various properties files.

      Or, if you just want to set a few properties, do this:

       Properties testProperties = new Properties();
       testProperties.setProperty("key1", "data1");
       testProperties.setProperty("key2", "data2");
       final MyConfiguration myConfig = ConfigFactory.create(MyConfiguration.class, testProperties);
       PropertiesAccessor.setProperties(myConfig);