我有一个单例类,我想模拟测试,如下所示:
public class MyClass {
private readonly static MyClass _instance = new MyClass();
public MyClass Instance { get { return this._instance; }}
private MyClass()
{
DoSomething();
}
}
由于MyClass
的私有构造函数有一些重要的逻辑,包括读取一些配置文件,我想模拟单例实例以进行测试。但是我无法看到这样做,因为我无法将属性Instance
标记为虚拟。
我认为我有两个机会,但我不知道哪个适合更好。第一个是使(私有)DomeSomething
- 方法可覆盖(意味着protected
和virtual
)并在派生类(模拟)中为它创建一些虚拟实现。然而,为了测试而修改我的类结构对我来说似乎并不合适。
另一种方法是使用this approach中建议的FormatterServices.GetUninitializedObject()
。我只是创建一个实例而不设置其成员的任何。之后,我可以使用一些更简单的逻辑通过反射初始化我需要的成员。无论如何,这对我来说似乎也很粗糙。
我还有其他机会吗?或者我必须在这两个烦人的人之间做出选择?
答案 0 :(得分:1)
我建议你试试Typemock Isolator。
它用于模拟单例的解决方案非常简单,不需要更改生产代码(您的私有方法仍然是私有的)。看看这个例子:
[TestMethod]
public void TestMethod1()
{
var fakeSingleton = Isolate.Fake.AllInstances<MyClass>();
Isolate.WhenCalled(() => fakeSingleton.someFunction()).WillReturn(true);
Assert.IsTrue(MyClass.Instance.someFunction());
}
在设置您喜欢的行为时,您正在通过调用Isolate.Fake.AllInstances<MyClass>()
创建假名,并且它也将在单例的实例上设置。
希望它有所帮助!
答案 1 :(得分:0)
是的,没有真正干净的方法来做到这一点。您可能需要更改类的接口或使用像您已经提到的那样的反射/ FormatterServices.GetUninitializedObject等技巧。