gpt4 book ai didi

java - 创建某种工厂时避免静态方法以实现可测试性

转载 作者:行者123 更新时间:2023-11-30 04:10:51 25 4
gpt4 key购买 nike

当重构一些代码时,我发现我有一个 new 调用,它创建了一个具体的类。

我正在寻找一种方法来避免调用创建具体类并提高可测试性,因此我创建了一种负责返回实例的工厂。然后,我使用 Spring 构造函数注入(inject),将工厂注入(inject)到被测系统中。

但是现在我面临着一个问题,如何使我的工厂中的方法静态化,同时具有良好的可测试性。根据 Misko Hevery 的说法,Static Methods are Death to testability但是我不清楚如何删除对 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;
}

...
}

我看到的唯一选择是保持工厂类型对象不变,即不使方法静态。

最佳答案

如果您要从应用程序中删除“new”,则需要某种机制来代表您创建对象。您可能需要检查三种机制。

第一个是依赖注入(inject)。 DI 容器允许您采用更加基于接口(interface)的方法并选择在运行时使用哪些实现。 Spring 是最流行的 DI 容器,而 CDI 是新的“标准”。 DI 很好,但它不一定是您想要在项目后期引入的东西。

第二种机制是 Java ServiceLoader,它允许您通过在类路径中添加和删除文件来更改组件的实现。您可能会发现这有点繁琐。

最后一种机制是使用静态方法(!!!),该方法读取工厂对象的类名属性,并使用 Class.forName().newInstance() 创建工厂对象你。这可能是最简单的方法。它为您提供了一个缝隙来注入(inject)新的模拟工厂。

避免静电是个好主意,但它们也有其用处。如果您了解所涉及的权衡,请使用它们。

关于java - 创建某种工厂时避免静态方法以实现可测试性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19635200/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com