TDD:测试构造函数设置属性是不是有意义?

Posted

技术标签:

【中文标题】TDD:测试构造函数设置属性是不是有意义?【英文标题】:TDD: Does it make sense to test that constructors set properties?TDD:测试构造函数设置属性是否有意义? 【发布时间】:2011-02-19 15:43:15 【问题描述】:

[TDD 新手]

我有一个具有属性颜色和品牌的汽车类。

在 TDD 中测试构造函数是否设置了这些属性是否有意义?还是我要等到需要时再测试(和实施)它?

那么,我是否要构建这样的测试:

(c#)

public class CarTests

  public void Constructor_Should_Set_Color()
  
    var car = new Car("Green", "Volvo");

    Assert.Equals(car.Color, "Green");
  

或者我是否要等到我有一个用例场景,例如,我必须从使用构造函数构建的列表中过滤所有绿色汽车,这将失败,因为汽车的颜色为 null?

直接测试构造函数真的有意义吗?那么 Equals() 呢?

【问题讨论】:

【参考方案1】:

我认为,理想情况下,您甚至不会拥有 Color 属性,直到您需要它。那时,您可能只使用一个 setter,或者您可以将它添加到构造函数中,或者添加一个新的构造函数。第二个选项使您处于具有两个(或更多)构造函数的状态 - 您可能会发现这很有帮助;在许多情况下(对于测试和“常规”代码),您可能不关心汽车是什么颜色。 正在测试你的设计。

【讨论】:

非常有趣,我将不得不审查我的设计。到现在为止,我在测试其他东西(如wheelCount)时使用构造函数将颜色设置为“blabla”。我并没有考虑仅仅为了可测试性而制作额外的构造函数。谢谢!【参考方案2】:

如果您实际上是在执行 TDD,则在需要存在的测试之前,您不会拥有属性 Color 和 Brand。

那个测试可能不应该像你的构造函数测试,而是一个关心颜色或品牌的其他东西的测试。

【讨论】:

【参考方案3】:

这似乎取决于开发人员/开发人员团队的情况和偏好,就像在一个测试方法中是否有几个不同的断言的问题一样。

虽然纯粹主义者可能希望获得接近 100% 的测试覆盖率,但也有一些开发人员只测试非平凡的东西。这两个极端之间的界限是模糊的。

【讨论】:

我发布的第二个选项不是也将涵盖此代码吗?由于第二个“过滤绿色汽车”测试不会通过,直到我在构造函数中设置属性。 Thomas:是的,它将覆盖它,假设在同一个类中使用了初始化值(IMO 并非总是如此)。否则,您要么是在进行集成测试,要么是在模拟构造函数的行为,而构造函数的行为又不会对其进行测试。【参考方案4】:

如果构造函数和 Equals 不太复杂,我通常不会费心去测试它们。如果它们变得更复杂或者我遇到了错误,那么我会添加测试。尽管这可能表明您的类变得过于复杂并且需要重构,但只有当您的类受到测试安全网的保护时,才能安全地进行重构。

从测试驱动的角度来看,您可能无论如何都不会从测试构造函数开始。对类或方法的需求会出现,因为在某些场景中它很有用并且应该在该上下文中进行测试。

【讨论】:

【参考方案5】:

这对我主要是 TDD 之前的心态提出了一个有趣的难题。

按照惯例,我对 OOP 的解释表明您的汽车类别应该代表现实。这意味着汽车应该在创建时获取它的颜色,之后不能更改它,除非通过某种“特殊”方法重新绘制汽车,并且只有在您的业务逻辑允许的情况下。

我认为 TDD 的答案是您无法对现实建模,而应该对应用程序中允许的行为更改范围进行建模。也许这辆车是在线订购应用程序中假设的未来汽车,或者是游戏中可以无缝更改颜色的模型。无论如何,上面的 Paeleo-OOP 方法在 TDD 哲学中是无效的。

为了尝试直接回答您的问题,我想说应该使用满足您的业务规则的最严格的语义来设置颜色属性。如果您当前已知的任何规格项目要求汽车能够动态更改其颜色,请将其编码为可设置属性。否则,它属于构造函数。一旦有人决定为您的项目的下一次迭代修改规范,请准备好撤销此决定。

【讨论】:

以上是关于TDD:测试构造函数设置属性是不是有意义?的主要内容,如果未能解决你的问题,请参考以下文章

Function、Array 和 Object 构造函数的长度属性是啥?

如何调用嵌套类的构造函数[重复]

空类的默认构造函数是公共的。但是怎么做?

通过构造函数或属性设置器进行依赖注入?

构造函数与普通函数的区别

带参数的Java私有构造函数[重复]