单元测试 - 我应该使用模拟还是使私有方法更加明显

时间:2012-11-23 08:45:53

标签: unit-testing mocking

我正在为我正在处理的应用程序的新模块寻找一些设计建议,特别是关于如何使设计可测试。

问题很常见 - 从数据库加载一些数据,对数据运行一些操作,并将结果保存到数据库。应用程序中的大多数其他模块具有以下模式:

private repo; //Set in constructor
public void Run() 
{
    Stuff stuff = repo.LoadStuff()
    Result result = RunOperationsInPrivateMethod(stuff); //private method
    repo.SaveResult(result);
}

所以为了测试这个,我看到我有几个选择:

  1. 注入一个模拟仓库,我可以用它来返回一个东西并验证结果。
  2. 将RunOperationsInPrivateMethod重构为受保护的访问,并进行测试 直接的操作。
  3. 我错过了其他选择吗?人们的偏好是什么?

1 个答案:

答案 0 :(得分:4)

一般情况下,不要测试私有方法,而是考虑您的私有方法是否真的应该是另一个类的公共方法。即,将您的对象分解为具有聚焦功能的较小对象。

例如,也许Run应该是

private repo; //Set in constructor
private IOperation operation; // injected in constructor or through dependency injection.
public void Run() 
{
    Stuff stuff = repo.LoadStuff()
    Result result = operation.Run(stuff); //private instance with public method
    repo.SaveResult(result);
}

然后Run将是一个操作类的公共方法

class SecretOperation : IOperation
{
   public void Run(Stuff stuff) { /* secret stuff */ }
}

然后,您也不必从数据库加载Stuff来测试,只需在专注于测试SecretOperation的fixture中创建一个东西。现在,您的单元测试可以更集中。