首先,模拟抽象类似乎很吸引人,但是抽象类的构造函数中的某些更改可能会破坏使用抽象类的模拟的单元测试。因此单元测试隔离不是100%。我的意思是没有人能保证抽象类的构造函数很简单。 (我的意思是不要扔,不要叫DB或类似奇怪的东西)。我知道构造函数应该很简单,但我不能保证它会一直保持简单。
我们的遗留代码库是抽象类繁重的,我真的不想模拟抽象类。 这是我更喜欢接口或抽象类的包装器接口的主要原因。有没有办法围绕基类构造函数的调用?说实话,我从来没有在TDD期间创建抽象类,但我无法改变系统的遗留部分。
我偏向于接口,但我想知道我提到的问题是真实的,或者可以被绕过。
答案 0 :(得分:1)
我会在抽象类上使用接口,除非有一个很好的参数反对它,组合比继承更好。
但您使用的是代码生产力工具,例如ReSharper或CodeRush吗?它们允许您有效地重构包括构造函数的代码,这将在诸如此类的实例中节省您的时间。
答案 1 :(得分:1)
我认为你提到的问题绝对是真实的。模拟抽象类并在测试中使用其构造函数或其具体方法之一实际上相当于测试了测试和抽象类的类。它不再是一个单元测试。嘲笑已经是脆弱的动物了,这只会给他们一个额外的理由来阻止你的测试。
我想解决方案几乎包含在你的问题中 - 使用接口。最好是你可以让你的遗留抽象类直接实现这些接口,但你也可以包装它们并依赖于包装器的接口而不是抽象类。
当涉及到依赖关系时,“接口偏向”可能不是一个坏主意。接口定义了一个合同,用于描述协作者可用的操作。抽象类(不是纯粹的抽象类,与接口相比毫无用处)描述了一类类在执行特定操作时的行为。您不希望依赖于如何并与细节相结合,您希望与高级抽象相结合。
答案 2 :(得分:0)
正如neoistheone所评论的那样,您可以使用Microsoft Fakes框架从抽象类生成存根。