【问题标题】:Testing a Static Methods Class had to be Changed to a Singleton For JUnit Testing测试静态方法类必须更改为单例以进行 JUnit 测试
【发布时间】:2012-06-27 15:30:20
【问题描述】:

我有一个静态方法类,Utils,它基本上用于实用方法,几乎​​每个类都使用它。它做一些事情,比如获取文件和其他基本的东西。我的测试人员将这个类更改为单例,这样每个使用 Utils 的类现在都必须调用 getInstance()。原因是除非是这种情况,否则他无法测试某些东西。在我看来,这在某些方面是错误的,这可能会导致问题。

public class Utils {

/**
 * Singleton method to allow for easier testing.
 * @return an instance of
 */
public synchronized static Utils getInstance() {
    if (instance == null) {
        instance = new Utils();
    }
    return instance;
}

public synchronized static void setInstance(Utils instance) {
    Utils.instance = instance;
}

/** Singleton to make testing easier **/
private static Utils instance = null;

public static boolean checkOSTen() {
    return getInstance()._checkOSTen();
}

private boolean _checkOSTen() {
    boolean autoPair = false;
    if (android.os.Build.VERSION.SDK_INT >= 10){   
        autoPair = true;
    }
    return autoPair;
}

}

顺便说一下,我有一个非常复杂的内部消息传递系统,它使用至少 7 个线程来发送消息,并且想看看静态方法调用与 Singleton 静态方法调用是否存在影响。

除此之外还有其他方法可以进行测试吗?似乎一些Java反射会得到你需要的东西。

【问题讨论】:

标签: java android static junit singleton


【解决方案1】:

您的测试人员可能会发现此代码难以测试,因为他们无法轻松更改 android.os.Build.VERSION.SDK_INT 的返回值,因此他们无法轻松测试根据此返回值使用的不同代码路径。通过使用实例方法,他们可以使用模拟框架来伪造_checkOSTen 方法以返回truefalse,具体取决于他们要测试的内容。

进行测试的另一种方法是根本不使用诸如此类的静态方法,而是使用类(可能称为DeviceCapabilities),该类将通过setter 或构造函数注入到需要了解的所有其他类中操作系统的版本。

然后,您的测试人员可以轻松地将 DeviceCapabilities 的实例传递给需要访问此信息的任何类。

也就是说,在您构建的这个阶段,进行这样的更改可能为时已晚,因此您的测试人员所做的更改是一个合理的折衷方案。

【讨论】:

  • 将其从静态方法更改为跨 9 个不同线程使用的 Singleton 实例有什么影响?这段代码会导致它现在使用更多/更少的内存吗?是否会跨线程调用同步瓶颈?
  • 我预计内存使用量的任何增加都是微不足道的。使用synchronize 可能会导致它成为瓶颈,但这完全取决于每个线程调用getInstance 的频率。唯一确定的方法是分析代码。但是,通过DeviceCapabilities 类切换到依赖注入样式应该可以消除这个瓶颈的风险,因为不需要synchronize
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-05
  • 1970-01-01
  • 1970-01-01
  • 2016-06-20
  • 2018-12-23
  • 2012-03-30
  • 2017-02-16
相关资源
最近更新 更多