对于我的最后一个 Java 项目,我对所有类进行了单元测试。每个类都有自己的接口和实现(即 Person 和 PersonImpl)。类仅通过接口相互交互,我使用模拟来独立于其他类测试每个类。它最终真的很痛苦,因为它破坏了我的 eclipse ctrl+click 导航,因为每个方法调用都是在接口上调用的。它还使业务代码有点混乱,每次我创建一个对象时都必须创建和传递依赖工厂,而该对象创建它的依赖关系完全没问题(除了测试之外)。我偶然发现了另一种形式的依赖注入,它似乎为我解决了这两个问题,我想知道是否有人能告诉我为什么这不是一个好主意。
这是一个简单的、人为的非现实示例……假设 File 和 FileFactory 是接口。
基于接口的构造函数 DI
public class Logger {
private File file;
public Logger(FileFactory fileFactory, String fileName) {
file = fileFactory.create(fileName);
file.createNewFile();
}
public void debug(String message) {
file.append("[debug] " + message);
}
public void error(String message) {
file.append("[error] " + message);
}
}
部分模拟依赖注入
public class Logger {
private File file;
public Logger(String fileName) {
file = createFile(fileName);
file.createNewFile();
}
public void debug(String message) {
file.append("[debug] " + message);
}
public void error(String message) {
file.append("[error] " + message);
}
public File createFile(String fileName) {
return new File(fileName);
}
}
在第二个例子中,没有接口或工厂,类之间的关系被保留,所以我可以 ctrl+click 到“createNewFile()”或“append”。在编写测试时,我可以使用 Mockito 对此类进行部分模拟,并指示它为“createFile(String)”返回一个模拟文件,因此我仍然可以在测试期间注入依赖项。我看到这样做的好处。有什么我没有看到的缺点吗?