C# 单元测试从抽象类B派生的类a
我需要对从抽象类a派生的类B进行单元测试,抽象类a有一些实现C# 单元测试从抽象类B派生的类a,c#,unit-testing,C#,Unit Testing,我需要对从抽象类a派生的类B进行单元测试,抽象类a有一些实现 我的问题是:如果您要对父类型(例如抽象的ClassB)或子类/派生类型(例如ClassA)进行单元测试,一般来说,您应该只通过对象的公共API进行测试。在这种情况下,这意味着测试具体的子类本身,抽象超类是一个实现细节 如果您觉得这会导致不必要的重复和/或您正在开发某种框架,并提供抽象基类(或更通用的接口)作为扩展点,那么您可以研究抽象基类的概念。契约测试摘要:编写针对公共API(接口或抽象基类)的测试,描述此接口的所有实现应保持的所有
我的问题是:如果您要对父类型(例如抽象的
ClassB
)或子类/派生类型(例如ClassA
)进行单元测试,一般来说,您应该只通过对象的公共API进行测试。在这种情况下,这意味着测试具体的子类本身,抽象超类是一个实现细节
如果您觉得这会导致不必要的重复和/或您正在开发某种框架,并提供抽象基类(或更通用的接口)作为扩展点,那么您可以研究抽象基类的概念。契约测试摘要:编写针对公共API(接口或抽象基类)的测试,描述此接口的所有实现应保持的所有不变量。然后在此接口的具体实现上运行这些测试
但是,如果抽象类/接口是公开的API,我只推荐契约测试。“如果我单独测试每个具体的实现,我会重复很多测试”——可以用更好的方法来减轻这种气味,例如用对象组合替换继承关系。编写单元测试的部分目的是维护代码的完整性。根据帕累托原则(80/20规则),您要测试的实现细节通常在派生类型中。所以 情节 典型情景 单元测试应为派生类型/子类编写,但单元测试应根据SOLID Liskov替换原则引用父类型: “程序中的对象应可替换为其子类型的实例,而不会改变该程序的正确性” 换句话说,您正在测试
狗
,但单元测试源代码将引用哺乳动物
:
Mammal pet = new Dog();
pet.Speak();
非典型情景
如果基本类型(例如哺乳动物
)包含要进行单元测试的可执行代码,则必须创建派生类型(例如狗
)的实例。例如,可以执行以下操作:
[TestCase]
public class MammalTest
{
[TestMethod]
AbstractMethodNameHere_YourTestCase_YourExpectedResults()
{
Mammal pet = new Dog();
// Here you could test the method that has been implemented
// in the base class.
Assert.IsTrue(pet.AbstractMethodNameHere());
}
}
为了重新迭代,您通常不会编写特定于基类的测试,因为实现细节通常在派生类型中
补充阅读
B
只是公共接口a
的一个实现细节。只需测试a
。显示相关代码,分享您的研究成果。不要要求“最佳实践”,问一个具体的问题。如何对抽象类进行单元测试?通过定义一个派生的非抽象类来进行测试?对于特定的实现,测试所有派生类就足够了。a=new B()
。然后测试您的实现。单元测试的目标之一是维护代码完整性。因此,我不同意“您应该只通过对象的公共API进行测试”的理念。如果您有一个不属于公共API的任务关键型方法,那么我会为它编写相应的单元测试。谢谢。您的回答非常有见解,因此我将其标记为解决方案。