我有两个班级
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最佳实践,我是否还应该创建第三个测试?
答案 0 :(得分:2)
我同意你的意见。重要的是方法的行为,而不是它的工作完成的地方。即使在交互测试方面,类和它的基类之间的“交互”在系统行为方面也不是“有趣的”。如果(比如)属性A复制最初是在基类中完成的,并且您从Base中删除了该功能,那么您的属性复制测试将检测到该失败,因此就回归而言,您的测试套件涵盖了重要的内容。如果将属性复制从基础移动到子级(反之亦然),则测试将报告没有回归 - 并且您的系统仍然可以正常运行。
答案 1 :(得分:0)
我还建议您考虑重构代码的可能性,以便无继承。检查这个' inheritance vs composition"线程了解更多详情。
在这种情况下,您可以注入当前的"基类功能"并确保您对ChildClass
的测试不依赖于BaseClass
当您编写单元测试(在TDD中执行)时,您只测试该类。在您的示例中,验证使用特定参数调用BaseClass.CopyProperties
的事实优于访问PropertyA
的检查,因为如果更改基类,子类测试将失败 - 但它们不应该
另一个想法可能是通过事件将BaseClass
与ChildClass
完全分离。 BaseClass
可以订阅ChildClass
的特定事件并执行其操作,但现在您的测试代码将更加清晰,因为您验证的是ProperyB
已设置且事件被触发。