C#:使用私有静态成员进行单元测试?

时间:2011-10-04 11:54:03

标签: c# unit-testing static private-members

我有一个类似这样的结构的类:

private static Dictionary<Contract, IPriceHistoryManager> _historyManagers = new Dictionary<Contract, IPriceHistoryManager>();

然后说两个方法,如:

 public void AddSth()
 {
    _historManagers.Add(new Contract(), new PriceHistoryManager());
 }

 public int CountDic()
 {
    return _historyManagers.Count(); 
 }

问题: 当运行单元测试时,没有办法“重置”字典,当我用类的单独实例创建多个单元测试时,“CountDic”会产生不可预测的结果,我无法测试监听。

问题: 这通常被认为是一种“坏”方法,如果是的话:如何做得更好/更多单位稳定? 如果没有:如何最好地进行单元测试?

THX。

2 个答案:

答案 0 :(得分:21)

不要害怕为测试目的公开公共操作。从Roy Osherove的“单元测试艺术”转述:当丰田制造汽车时,有可用的测试点。当英特尔构建芯片时,可以使用测试点。汽车或芯片的接口仅用于测试。为什么我们不为软件做同样的事情? ResetHistory()方法是否会完全破坏您的API?

如果答案为yes,则创建方法,但制作方法internal。然后,您可以使用程序集InternalsVisibleTo将单元暴露给单元测试库。您有一个可用的方法100%用于测试,但您的公共API没有变化。

答案 1 :(得分:3)

在您的示例中,CountDic不可预测:它应该在调用AddSth()之前返回一个。

所以:

[Test]
public void Test()
{
    var item = new ClassUnderTest();
    int initialCount = item.CountDic();

    item.AddSth();

    int finalCount = item.CountDic();

    Assert.That(finalCount == initialCount + 1);
}

但是,一般来说,测试维护状态的类可能会很棘手。有时需要打破维护状态的类的部分(在您的情况下,字典)并将其移动到另一个类。然后,您可以模拟该“存储”类并通过构造函数传递它。