我有一个如下所示的 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;
}
}
Run Code Online (Sandbox Code Playgroud)
由于这个类的真正逻辑在于convertData()方法,所以我想为这个方法编写一个单元测试。所以我读了这篇文章
很多人说需要测试私有方法是一种设计味道。怎样才能做得更好呢?
我看到两种方法:
convertData()使用公共 api 将方法提取到某个实用程序类中。但我认为这也是一种不好的做法,因为此类实用程序类将违反单一责任原则,除非我创建大量可能只有一两个方法的实用程序类。
编写第二个允许注入的构造函数dbCon,这允许我注入数据库连接的模拟版本并针对公共doSomething()方法运行测试。这将是我首选的方法,但也有关于模拟的需要如何也是一种代码味道的讨论。
对于这个问题有什么最佳实践吗?
将 ConvertData() 方法提取到某个具有公共 api 的实用程序类中。但我认为这也是一种不好的做法,因为这样的实用程序类将违反单一职责原则,除非我创建大量可能只有一两个方法的实用程序类。
你对此的解释是错误的。这正是 SRP 和 SoC (关注点分离)所建议的
public interface MyDataConverter {
MyData convertData(MyData data);
}
public class MyDataConverterImplementation implements MyDataConverter {
public MyData convertData(MyData data) {
// Some complex logic...
return data;
}
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
MyClass现在更加诚实地了解执行其所需功能所需的内容。
它还可以通过注入模拟依赖项来单独进行单元测试。
| 归档时间: |
|
| 查看次数: |
463 次 |
| 最近记录: |