是否有任何最佳实践来测试使用继承的类?

时间:2013-05-23 13:34:30

标签: unit-testing testing inheritance language-agnostic

是否有测试使用继承的类的最佳实践?

例如,如果我有一个BaseNode类

public class BaseNode
{
    int testInt;//attribute

    //assume getters and setters and constructor

    public function somethingComplicated()
    {
        //put complex code here
    }
}

和另一个名为InputNode的类,它继承自BaseNode。

public class InputNode extends BaseNode
{
    int secondTest;//attribute

    //assume getters and setters and constructor
}

如果我为两个类编写getter和setter,我需要测试什么?

你真的必须在BaseNode和InputNode类中为getTestInt()编写测试吗? 如果在InputNode类中为getTestInt()编写测试,那么它是否也会自动计为BaseNode类的测试?

编辑问题以使其更具体。我不只是询问吸气剂和吸尘剂。

如果在Base类中为somethingComplicated()编写测试,您会自动认为该测试对InputNode类有效吗?

我最初使用getter和setter作为一个简单的例子来尝试和说明这个概念。我并不是说我只想测试吸气剂和制定者。

3 个答案:

答案 0 :(得分:2)

首先,setter是代码气味,在很大程度上是因为它们增加了测试的复杂性。他们这样做是因为它们可能会增加对象可能存在的状态数量。

最佳做法是:

  1. 最小化setter
  2. 每个派生对象都必须通过每个基类测试,因此请确保将测试设置为完成此操作。如果它们没有通过,则意味着基本实例不是liskov可替代的。这样做的好处是你不需要为每个派生类编写一套完整的新测试。
  3. 您需要进行测试,以明确确保新的setter和行为不会与基类行为不正确地进行交互。

答案 1 :(得分:1)

您还必须测试基类,因为基类的方法/ getter可能会受到基类中的代码的影响:

  • 由派生类覆盖
  • 派生类中的代码可能会导致副作用(通过更改基类字段等)

答案 2 :(得分:1)

为了证明Liskov的可替代性,需要为每个派生类传递基类的全套测试。此外,需要存在派生类提供的专业化测试。出于这个原因,许多人选择以反映被测试类的方式组织测试类。

给定InputNode的子类BaseNode,我们可能会有类似这样的测试类 [欢迎修改我的Java语法]:

public class BaseNodeTest {
    protected BaseNode getBaseNode () {
        return new BaseNode();
    }

    public void test_complicated_BaseNode_behavior () {
        BaseNode bn = getBaseNode();
        // actual test code...
    }
}

public class InputNodeTest extends BaseNodeTest {
    protected BaseNode getBaseNode () {
        return new InputNode();
    }

    public void test_InputNode_specific_behavior () {
        InputNode in = getBaseNode();
        // actual test code...
    }
}

关键点是InputNodeTest将针对BaseNodeTest运行InputNode中的所有测试,并添加自己的测试。这可以确保InputNode可以在预期BaseNode的任何地方使用。