[英]Avoiding Static method for testability when creating a sort of Factory
重构某些代码时,我发现有一个new
调用创建了一个具体的类。
我一直在寻找一种避免调用创建具体类并提高可测试性的方法,因此我创建了一种Factory,负责为我返回一个实例。 然后,我使用Spring构造函数注入将工厂注入被测系统。
但是,现在我面临着一个问题,那就是在我的工厂中使该方法静态化,同时又具有良好的可测试性。 根据Misko Hevery的说法, 静态方法将导致可测试性的死亡,但是我不清楚如何删除对new的调用,具有良好的单元测试以及避免静态方法的调用。
这是使用工厂的类的摘录。 我正在测试此类中的方法,这些方法利用了已构造的(和模拟的)columnFamilyTemplate:
protected AlertFieldMatcher(ColumnFamilyTemplateBuilder columnFamilyTemplateBuilder, Keyspace keyspace,
T2JsonUtilInterface jsonUtil) {
this.columnFamilyTemplate = columnFamilyTemplateBuilder.build(keyspace, CF_ALERT);
this.jsonUtil = jsonUtil;
}
这是工厂,现在我必须在测试中模拟SUT中的方法(如上所述):
public class DefaultColumnFamilyTemplateBuilder
implements ColumnFamilyTemplateBuilder {
@Override
public ColumnFamilyTemplate<String, String> build(Keyspace keyspace,
String columnFamily) {
ColumnFamilyTemplate<String, String> builtTemplate =
new ThriftColumnFamilyTemplate<String, String>
(keyspace,
columnFamily,
StringSerializer.get(),
StringSerializer.get());
return builtTemplate;
}
...
}
我看到的唯一选择是将Factory类型的对象保持不变,即不使方法静态。
如果要从应用程序中删除“新”,则需要某种机制来代表您创建对象。 您可能需要检查三种机制。
首先是依赖注入。 DI容器使您可以采用基于接口的方法,并选择在运行时使用哪些实现。 Spring是最受欢迎的DI容器,而CDI是新的“标准”容器。 DI很好,但是不一定要在项目后期引入。
第二种机制是Java ServiceLoader,它允许您通过从类路径中添加和删除文件来更改组件的实现。 您可能会发现这一点。
最后一种机制是使用静态方法(!!!!)读取属性,该属性是工厂对象的类名,并使用Class.forName()。newInstance()为您创建工厂对象。 这可能是最简单的方法。 它给您一个接缝,以注入新的模拟工厂。
避免静电是一个好主意,但是它们有自己的位置。 如果您了解所涉及的取舍,请使用它们。
您无需显式创建工厂。
将新实例的创建提取到类中的受保护方法中,与创建工厂方法完全相同,只是提供new ThriftColumnFamilyTemplate(...)
作为默认实现。
在单元测试中,sut将是类的部分模拟版本,模拟了工厂方法,而不是真实的类。 使用这种方法,未经测试的唯一代码将是工厂方法,即一行。 对于部分模拟,您可以使用EasyMock IMockBuilder 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.