我是否使用垫片在我测试的方法中填充公共方法?

时间:2013-06-05 16:05:04

标签: c# unit-testing microsoft-fakes

我还在试图找出正确使用Microsoft Fakes中的Shims的内容。 我理解它适用于运行时方法拦截器,它允许您为几乎任何方法提供自己的实现,但让我问一个更单元的暴躁类型问题。 在下面的方法中,我是否应该填充PUBLIC STATIC方法并删除可覆盖的方法base.ResolveDate(comparisonSeries,targetDate)?我应该只测试ResolveDate()里面的内容吗?这似乎是您使用单元测试正确测试方法的方式。 只测试方法,除非方法嵌套了私有方法调用,在这种情况下,你将通过这些私有方法运行单元测试(根据Roy Osherove的“单元测试艺术”,你不要独立测试私有方法)。 / p>

public override DateTime ResolveDate(ISeries comparisonSeries, DateTime targetDate)
{
   if (comparisonSeries == null)
   {
      throw new ArgumentNullException("comparisonSeries");
   }

   switch (comparisonSeries.Key)
   {               
      case SeriesKey.SomeKey1:
      case SeriesKey.SomeKey2:
      case SeriesKey.SomeKey3:
      case SeriesKey.SomeKey4:
      case SeriesKey.SomeKey5:
      return DateHelper.PreviousOrCurrentQuarterEnd(targetDate);
   }
   return base.ResolveDate(comparisonSeries, targetDate);
}

2 个答案:

答案 0 :(得分:1)

在大多数情况下,没有必要将目标方法与它调用的私有类或成员隔离开来。假设DateHelper.PreviousOrCurrentQuarterEnd和base.ResolveDate有自己的单元测试,可以对重写的ResolveDate方法进行单元测试以验证

a)对于SeriesKey的特殊值,它返回DateHelper.PreviousOrCurrentQuarterEnd期望的结果。 b)对于SeriesKey的所有其他值,它返回一个从base.ResolveDate预期的结果。

但是,如果很难设置目标方法的依赖关系,例如使用遗留代码时,可以使用Fakes将目标方法与其依赖关系隔离开来。在此示例中,您可以存根ISeries接口并填充DateHelper.PreviousOrCurrentQuarterEnd方法或base.ResolveDate方法。根据经验,只有当真实对象具有使单元测试过于缓慢,脆弱或复杂的依赖性时,才能使用真实对象开始单元测试并使用存根或填充程序。考虑重构那些在您控制之下的依赖项,以便在没有假货的情况下进行测试。

答案 1 :(得分:0)

Microsoft Fakes的最佳用途之一是进行集成测试单元测试的测试。例如,一种准备一些数据并将其写入文件的方法(技术上某些标准过于复杂)可以使用Shim重新路由File.Write方法,允许您单独测试准备代码。

另一方面,需要垫片的设计在技术上是不好的。在许多情况下它会发生,但是在可能的情况下,方法应该只做一件事并使用依赖注入来保持不相关的部分分开。然后,您可能会有一个方法,例如SaveFile(SomeObject source, IFileManager manager),您可以在其中传入写入逻辑的存根。

在您的情况下,这是单元测试中较困难的部分之一。基类可能在其他地方进行了测试,你不想在方法的测试中测试它的代码 - 对于DateHelper调用也是如此。

但问题是,您的测试将依赖于两种方法的填充程序。如果实现更改,但结果没有,则您的测试可能会失败。这是测试时应该避免的。结果的变化应该会破坏测试,但重构或优化不应该。

同时,考虑到你的方法的范围,我可能还是使用垫片。