单元测试从抽象类B派生的类A.

时间:2015-06-08 13:10:54

标签: c# unit-testing

我需要对从抽象类A派生的类B进行单元测试,该抽象类有一些实现。

我的问题是:你应该单元测试父类型(例如抽象ClassB)还是子类/派生类型(例如ClassA

2 个答案:

答案 0 :(得分:0)

通常,您应该只测试对象的公共API。在这种情况下,这意味着测试具体的子类本身,抽象的超类是一个实现细节。

如果您认为这会导致不必要的重复和/或您正在开发某种框架并提供抽象基类(或更一般的接口)作为扩展点,您可能会研究contract tests的概念。合同测试摘要:针对公共API(接口或抽象基类)编写测试,描述应该为此接口的所有实现保留的所有不变量。然后在此接口的具体实现上运行这些测试。

如果抽象类/接口是公开公开的API,我只会建议合同测试。如果我单独测试每个具体的实现,我会复制大量的测试,并且可以更好的方式减轻因素,例如:通过用对象组合替换继承关系。

答案 1 :(得分:0)

部分测试的编写部分是为了维护代码的完整性。为了与 Pareto原则(80/20规则)保持一致,您要测试的实现细节通常是派生类型。所以...

方案

典型情景

单元测试应写为 派生类型/子类,但单元测试实现应根据SOLID Liskov替换引用父类型原理

“程序中的对象应该可以替换为其子类型的实例,而不会改变该程序的正确性"

换句话说,您正在测试Dog,但单元测试源代码将引用Mammal

Mammal pet = new Dog();
pet.Speak();

非典型场景

如果基类型(例如Mammal)包含您要进行单元测试的可执行代码,则必须创建派生类型的实例(例如Dog)。例如,你可以这样做:

[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());
    }
}

要重新迭代,通常不会编写特定于基类的测试,因为实现细节通常在派生类型中。

补充阅读