如何处理TDD中的接口过度使用?

Chr*_*ris 23 c# tdd unit-testing interface

我注意到,当我在做TDD时,它经常导致非常大量的接口.对于具有依赖项的类,它们以通常的方式通过构造函数注入:

public class SomeClass
{
    public SomeClass(IDependencyA first, IDependency second)
    {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

结果是几乎每个类都将实现一个接口.

是的,代码将被解耦并且可以非常容易地进行单独测试,但是还会有额外的间接级别让我觉得有点......不安.有些事情感觉不对劲.

任何人都可以分享其他不涉及如此大量使用接口的方法吗?

你们其他人怎么样?

Jef*_*nal 13

您的测试告诉您重新设计课程.

有时您无法避免传递需要存根的复杂协作者以使您的类可测试,但您应该寻找方法为他们提供这些协作者的输出,并考虑如何重新安排他们的交互消除复杂的依赖关系.

例如,而不是提供TaxCalculator一个ITaxRateRepository(命中时的数据库CalculateTaxes),创建之前获得这些值TaxCalculator的实例,并将它们提供给它的构造:

// Bad! (If necessary on occasion)
public TaxCalculator(ITaxRateRepository taxRateRepository) {}

// Good!
public TaxCalculator(IDictonary<Locale, TaxRate> taxRateDictionary) {}
Run Code Online (Sandbox Code Playgroud)

有时这意味着你必须做出更大的改变,调整对象的生命周期或重组大量的代码,但是一旦我开始寻找它,我经常会发现低洼的果实.

有关减少对依赖项依赖性的优秀技术综述,请参阅Mock Eliminating Patterns.


dty*_*dty 5

不要使用接口!大多数模拟框架都可以模拟具体的类.

  • 为什么不?创建一个只在生产代码中只有一个实现的接口是没有意义的,如果你创建它的唯一原因是你可以模拟它. (7认同)
  • 在c#中,声明虚拟方法比创建冗余接口更好.请参阅http://stackoverflow.com/questions/90851/is-creating-interfacesfor-almost-every-class-justified-or-are-interfaces-overus?lq=1 (2认同)