Java 通过在重构之前重写私有类变量作为初始步骤来测试方法
为使用Java 通过在重构之前重写私有类变量作为初始步骤来测试方法,java,unit-testing,legacy-code,Java,Unit Testing,Legacy Code,为使用private配置变量(config)的方法编写单元测试的最佳方式是什么,例如mysetProperties(见下文)。我尝试使用反射和Makito来覆盖它,但失败了,但没有成功。我意识到改变设计使代码更易于测试是最好的,但我想在重构代码之前创建一些单元测试 public class MainClass { private final java.lang.String config = "app.properties"; public TestClass() {
private
配置变量(config
)的方法编写单元测试的最佳方式是什么,例如mysetProperties
(见下文)。我尝试使用反射和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;
}
}
}
这表明设计有缺陷;不要硬编码这样的东西。更好的是,确定该类的适当责任是什么,并按优先顺序递减:
- 传入具有强类型配置属性的对象
- 传入带有配置属性的
映射
- 为属性文件传入一个
InputStream
由于jar中永远无法使用
File
对象,所以您不应该让这样的接口比InputStream
或Reader
更具体,这样您就可以始终从jar类路径传入流。所以您可以使用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;
}
公共类属性直到{
私有静态属性;
私有静态记录器=Logger.getLogger(PropertyUtil.class);
私有财产直到(){
}
public void setProperty(){
字符串filePath=System.getenv(“JAVA_HOME”)+“/lib”+“/my_file.properties”;
prop=新属性();
try(InputStream输入=新文件InputStream(文件路径)){
道具载荷(输入);
}捕获(IOEX异常){
logger.error(“读取属性文件时出错”+ex);
}
}
公共静态字符串getProperty(字符串键){
if(附件containsKey(图例)){
返回prop.getProperty(键);
}否则{
返回null;
}
}
公共静态getProperty(字符串键,类claz){
if(claz.getName().equals(Integer.class.getName())){
返回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())){
返回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())){
返回claz.cast(prop.getProperty(key));
}
返回null;
}
通过提取一个带有参数的方法来重构一点,该参数接受一个输入流。调用这个新方法(可能受包保护)从旧方法开始。针对新方法编写测试。然后进行更多重构。发布setProperties
方法的完整代码,或者只模拟配置文件的问题?问题是模拟或重写私有变量。我想要一种在单元测试期间更改该私有变量值的方法。请删除java.lang.
beforeString
@luk2302为什么?在限定String时有风险吗?“我不能使用反射”-您实际尝试了什么?您看到了吗?我知道这个问题,我正在寻找重构前的单元测试解决方案。不幸的是,这段代码不是我自己的,无法更改。