1

What is the best way of writing a unit test for a method, such as my setProperties (see below), that uses a private configuration variable (config). I tried but failed to override it using reflection and Makito, but without success. I realize that changing the design to make the code easier to test is best, but I want to created some unit tests before I refactor the code.

public class MainClass {
    private final java.lang.String config = "app.properties";

    public TestClass() {
        try {
            setProperties();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setProperties() throws Exception {
        try {
            InputStream input = new BufferedInputStream(new FileInputStream(config));
            ..
            ..
        } catch (Exception exception) {
            throw exception;
        }
    }
}
Raedwald
  • 46,613
  • 43
  • 151
  • 237
BoomRamada
  • 121
  • 1
  • 2
  • 11

3 Answers3

1

Do refactor a tiny bit by extracting a method with a parameter that takes an input stream. Call this new method (probably package-protected) from the old one. Write tests against the new method. Then do more refactorings.

Arne Deutsch
  • 14,629
  • 5
  • 53
  • 72
0

This is an indication of a broken design; don't hard-code things like this. Better yet, determine what the appropriate responsibility for this class is, and, in decreasing order of preference:

  • pass in an object with the configuration properties, strongly typed
  • pass in a Map with the configuration properties
  • pass in an InputStream for the properties file

As File objects are never available from a jar, you shouldn't ever make interfaces like this more specific than InputStream or Reader, so that you can always pass in streams from your jar classpath.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
  • I'm aware of the issue, I'm after solution for unit test before refactor. Unfortunately this code is not own by me and unchangeable. – BoomRamada May 04 '18 at 05:50
0

So you can use Properties class in Java for this. Please have a look at this code.

public class PropertyUtil {

        private static Properties prop;

        private static Logger logger = Logger.getLogger(PropertyUtil.class);

        private PropertyUtil() {

        }

        public void setProperty() {
            String filePath = System.getenv("JAVA_HOME") + "/lib" + "/my_file.properties";
            prop = new Properties();

            try (InputStream input = new FileInputStream(filePath)) {
                prop.load(input);
            } catch (IOException ex) {
                logger.error("Error while reading property file " + ex);
            }
        }

        public static String getProperty(String key) {
            if (prop.containsKey(key)) {
                return prop.getProperty(key);
            } else {
                return null;
            }
        }

        public static <T> T getProperty(String key, Class<T> claz) {

            if (claz.getName().equals(Integer.class.getName())) {
                return claz.cast(Integer.parseInt(prop.getProperty(key)));
            }
            if (claz.getName().equals(Long.class.getName())) {
                return claz.cast(Long.parseLong(prop.getProperty(key)));
            }
            if (claz.getName().equals(Boolean.class.getName())) {
                return claz.cast(Boolean.parseBoolean(prop.getProperty(key)));
            }
            if (claz.getName().equals(Double.class.getName())) {
                return claz.cast(Double.parseDouble(prop.getProperty(key)));
            }
            if (claz.getName().equals(String.class.getName())) {
                return claz.cast(prop.getProperty(key));
            }

            return null;
        }
Naresh Bharadwaj
  • 192
  • 1
  • 12