我应该单元测试基本方法吗?

时间:2014-12-09 17:02:12

标签: unit-testing tdd code-coverage agile

我有两个班级

public abstract class BaseClass
{
  public string PropertyA {get; set;}

  public virtual object CopyProperties(BaseClass other)
  {
    other.PropertyA = this.PropertyA;
  }
}

和一个继承自它的类

public class ChildClass : BaseClass
{
  public string PropertyB {get; set;}

  public virtual object CopyProperties(BaseClass other)
  {
    other.PropertyB = this.PropertyB;
    base.CopyProperties(other);
  }
}

我自然而然地测试过这样复杂的逻辑!

我有两个测试:

  

Ensure_calling_CloneProperties_copies_PropertyA()   Ensure_calling_CloneProperties_copies_PropertyB()

我想知道是否还需要进行以下测试

  

Ensure_calling_CloneProperties_on_ChildClass_calls_base()

我个人认为我们应该在ChildClass上测试CloneProperties的行为,我们需要验证当我们调用clone PropertyA和PropertyB都被正确复制时 - 我们不需要(或想要)知道如何实现这一点。然而,一位同事不同意。

鉴于敏捷和TDD最佳实践,我是否还应该创建第三个测试?

2 个答案:

答案 0 :(得分:2)

我同意你的意见。重要的是方法的行为,而不是它的工作完成的地方。即使在交互测试方面,类和它的基类之间的“交互”在系统行为方面也不是“有趣的”。如果(比如)属性A复制最初是在基类中完成的,并且您从Base中删除了该功能,那么您的属性复制测试将检测到该失败,因此就回归而言,您的测试套件涵盖了重要的内容。如果将属性复制从基础移动到子级(反之亦然),则测试将报告没有回归 - 并且您的系统仍然可以正常运行。

答案 1 :(得分:0)

我还建议您考虑重构代码的可能性,以便无继承。检查这个' inheritance vs composition"线程了解更多详情。

在这种情况下,您可以注入当前的"基类功能"并确保您对ChildClass的测试不依赖于BaseClass

中的代码

当您编写单元测试(在TDD中执行)时,您只测试该类。在您的示例中,验证使用特定参数调用BaseClass.CopyProperties的事实优于访问PropertyA的检查,因为如果更改基类,子类测试将失败 - 但它们不应该

另一个想法可能是通过事件将BaseClassChildClass完全分离。 BaseClass可以订阅ChildClass的特定事件并执行其操作,但现在您的测试代码将更加清晰,因为您验证的是ProperyB已设置且事件被触发。