通过在重构之前重写私有类变量作为初始步骤来测试方法

时间:2018-05-04 05:28:54

标签: java unit-testing legacy-code

为方法编写单元测试的最佳方法是什么,例如我的setProperties(见下文),它使用private配置变量(config)。我尝试但未能使用反射和Makito覆盖它,但没有成功。我意识到改变设计以使代码更容易测试是最好的,但我想在重构代码之前创建一些单元测试

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;
        }
    }
}

3 个答案:

答案 0 :(得分:1)

通过使用带有输入流的参数提取方法来重构一点点。从旧的方法中调用这个新方法(可能是受包保护的)。针对新方法编写测试。然后做更多的重构。

答案 1 :(得分:0)

这表明设计已经破损;不要硬编码这样的事情。更好的是,确定这个类的适当责任是什么,并且按优先顺序递减:

  • 使用配置属性传递一个对象,强类型
  • 使用配置属性传递Map
  • 传递属性文件的InputStream

由于File对象永远不会从jar中获取,因此您不应该使这样的接口比InputStreamReader更具体,这样您就可以随时传入来自jar类路径的流。

答案 2 :(得分:0)

因此,您可以在Java中使用Properties类。请看一下这段代码。

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;
        }