yey*_*man 46 singleton unit-testing
我已经使用Visual Studio Team Edition测试框架准备了一些自动测试.我希望其中一个测试按照在程序中完成的正常方式连接到数据库:
string r_providerName = ConfigurationManager.ConnectionStrings["main_db"].ProviderName;
Run Code Online (Sandbox Code Playgroud)
但是我在这一行中收到了一个例外.我想这是因为ConfigurationManager是一个单例.你怎么能解决单元测试中的单例问题?
谢谢你的回复.所有这些都非常有启发性.
bni*_*dyc 13
您可以使用构造函数依赖注入.例:
public class SingletonDependedClass
{
private string _ProviderName;
public SingletonDependedClass()
: this(ConfigurationManager.ConnectionStrings["main_db"].ProviderName)
{
}
public SingletonDependedClass(string providerName)
{
_ProviderName = providerName;
}
}
Run Code Online (Sandbox Code Playgroud)
这允许您在测试期间将连接字符串直接传递给对象.
此外,如果您使用Visual Studio Team Edition测试框架,您可以使用参数private构建器,并通过访问器测试该类.
实际上我用嘲弄来解决这类问题.例:
你有一个依赖于单身的类:
public class Singleton
{
public virtual string SomeProperty { get; set; }
private static Singleton _Instance;
public static Singleton Insatnce
{
get
{
if (_Instance == null)
{
_Instance = new Singleton();
}
return _Instance;
}
}
protected Singleton()
{
}
}
public class SingletonDependedClass
{
public void SomeMethod()
{
...
string str = Singleton.Insatnce.SomeProperty;
...
}
}
Run Code Online (Sandbox Code Playgroud)
首先SingletonDependedClass需要重构以将Singleton实例作为构造函数参数:
public class SingletonDependedClass
{
private Singleton _SingletonInstance;
public SingletonDependedClass()
: this(Singleton.Insatnce)
{
}
private SingletonDependedClass(Singleton singletonInstance)
{
_SingletonInstance = singletonInstance;
}
public void SomeMethod()
{
string str = _SingletonInstance.SomeProperty;
}
}
Run Code Online (Sandbox Code Playgroud)
测试SingletonDependedClass(使用Moq模拟库):
[TestMethod()]
public void SomeMethodTest()
{
var singletonMock = new Mock<Singleton>();
singletonMock.Setup(s => s.SomeProperty).Returns("some test data");
var target = new SingletonDependedClass_Accessor(singletonMock.Object);
...
}
Run Code Online (Sandbox Code Playgroud)
书中的示例:有效地使用旧版代码
同样在这里给出相同的答案:https: //stackoverflow.com/a/28613595/929902
要在测试工具中运行包含单例的代码,我们必须放松单例属性.这是我们如何做到的.第一步是向singleton类添加一个新的静态方法.该方法允许我们替换单例中的静态实例.我们称之为 setTestingInstance.
public class PermitRepository
{
private static PermitRepository instance = null;
private PermitRepository() {}
public static void setTestingInstance(PermitRepository newInstance)
{
instance = newInstance;
}
public static PermitRepository getInstance()
{
if (instance == null) {
instance = new PermitRepository();
}
return instance;
}
public Permit findAssociatedPermit(PermitNotice notice) {
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
现在我们有了setter,我们可以创建一个PermitRepository的测试实例并进行设置.我们想在我们的测试设置中编写这样的代码:
public void setUp() {
PermitRepository repository = PermitRepository.getInstance();
...
// add permits to the repository here
...
PermitRepository.setTestingInstance(repository);
}
Run Code Online (Sandbox Code Playgroud)
你在这里面临一个更普遍的问题.如果误用,单身人士会阻碍测试.
我已经在解耦设计的背景下对这个问题进行了详细的分析.我会试着总结一下我的观点:
| 归档时间: |
|
| 查看次数: |
53898 次 |
| 最近记录: |