我有一个类如下的Java类:
public class MyClass {
/** Database Connection. */
private dbCon;
public MyClass() {
dbCon = ...
}
public void doSomethingWith(MyData data) {
data = convertData(data);
dbCon.storeData(data);
}
private MyData convertData(MyData data) {
// Some complex logic...
return data;
}
}
因为这个类的真正逻辑在于convertData()
方法,所以我想为这个方法编写一个单元测试。
所以我读了这篇文章
How do I test a private function or a class that has private methods, fields or inner classes?
很多人都说测试私有方法的需要是设计气味。如何做得更好?
我看到两种方法:
使用公共API将convertData()
方法解压缩到某个实用程序类中。但我认为这也是不好的做法,因为这样的实用程序类会违反单一责任原则,除非我用一两种方法创建了很多实用程序类。
编写第二个允许注入dbCon
的构造函数,这允许我注入数据库连接的模拟版本并对公共doSomething()
方法运行我的测试。这将是我的首选方法,但也有关于模拟的需求如何也是代码气味的讨论。
是否有关于此问题的最佳做法?
答案 0 :(得分:3)
使用public api将convertData()方法解压缩到某个实用程序类中。但我认为这也是不好的做法,因为这样的实用程序类会违反单一责任原则,除非我用一两种方法创建了很多实用程序类。
你解释这是错误的。这正是SRP和SoC (关注点分离)建议的
public interface MyDataConverter {
MyData convertData(MyData data);
}
public class MyDataConverterImplementation implements MyDataConverter {
public MyData convertData(MyData data) {
// Some complex logic...
return data;
}
}
convertData
实现现在可以独立于MyClass
编写第二个允许注入dbCon的构造函数,这允许我注入数据库连接的模拟版本并对公共doSomething()方法运行我的测试。这将是我的首选方法,但也有关于模拟的需求如何也是代码气味的讨论。
再次错了。研究显性依赖原则。
public class MyClass {
private DbConnection dbCon;
private MyDataConverter converter;
public MyClass(DbConnection dbCon, MyDataConverter converter) {
this.dbCon = dbCon;
this.converter = converter;
}
public void doSomethingWith(MyData data) {
data = converter.convertData(data);
dbCon.storeData(data);
}
}
MyClass
现在对于执行其所需功能所需的内容更为诚实。
它也可以通过注入模拟依赖项进行单元测试。