- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
Effective Java 第 3 项(使用私有(private)构造函数或枚举类型实现单例属性)指出:
Making a class a singleton can make it difficult to test its clients, as it's impossible to substitute a mock implementation for a singleton unless it implements an interface that serves as its type.
出于测试目的,为什么仅实例化一个单例实例并测试其 API 是不够的?那不是客户会消费的东西吗?引用似乎暗示测试单例将涉及“模拟实现”,但为什么有必要这样做?
我看到过各种“解释”,它们或多或少是对上述引述的改写。有人可以进一步解释这一点,最好是用代码示例吗?
最佳答案
如果您的单例正在对数据库执行操作或将数据写入文件怎么办?您不希望在单元测试中发生这种情况。您可能希望模拟该对象以在内存中执行一些操作,这样您就可以验证它们而不会产生永久的副作用。单元测试应该是独立的,不应创建与数据库的连接或与外部系统执行其他可能失败的操作,然后由于不相关的原因导致单元测试失败。
使用伪 java 的示例(我是 C# 开发人员):
public class MySingleton {
private static final MySingleton instance = new MySingleton();
private MySingleton() { }
public int doSomething() {
//create connection to database, write to a file, etc..
return something;
}
public static MySingleton getInstance() {
return instance;
}
}
public class OtherClass {
public int myMethod() {
//do some stuff
int result = MySingleton.getInstance().doSomething();
//do some other suff
return something;
}
}
为了测试myMethod
,我们必须进行实际的数据库调用、文件操作等
@Test
public void testMyMethod() {
OtherClass obj = new OtherClass();
//if this fails it might be because of some external code called by
//MySingleton.doSomething(), not necessarily the logic inside MyMethod()
Asserts.assertEqual(1, obj.myMethod());
}
如果 MySingleton
是这样的:
public class MyNonSingleton implements ISomeInterface {
public MyNonSingleton() {}
@Override
public int doSomething() {
//create connection to database, write to a file, etc..
return something;
}
}
然后您可以像这样将它作为依赖注入(inject)到 MyOtherClass 中:
public class OtherClass {
private ISomeInterface obj;
public OtherClass(ISomeInterface obj) {
this.obj = obj;
}
public int myMethod() {
//do some stuff
int result = obj.doSomething();
//do some other stuff
return something;
}
}
然后你可以这样测试:
@Test
public void TestMyMethod() {
OtherClass obj = new OtherClass(new MockNonSingleton());
//now our mock object can fake the database, filesystem etc. calls to isolate the testing to just the logic in myMethod()
Asserts.assertEqual(1, obj.myMethod());
}
关于java - 为什么单例类很难测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25273210/
我最近购买了《C 编程语言》并尝试了 Ex 1-8这是代码 #include #include #include /* * */ int main() { int nl,nt,nb;
早上好!我有一个变量“var”,可能为 0。我检查该变量是否为空,如果不是,我将该变量保存在 php session 中,然后调用另一个页面。在这个新页面中,我检查我创建的 session 是否为空,
我正在努力完成 Learn Python the Hard Way ex.25,但我无法理解某些事情。这是脚本: def break_words(stuff): """this functio
我是一名优秀的程序员,十分优秀!