【问题标题】:Derivation, composition, constructors, interfaces and TDD派生、组合、构造函数、接口和 TDD
【发布时间】:2015-07-26 15:01:39
【问题描述】:

在开发 TDD 时,您的对象会随着代码的发展而“增长”。首先它们只包含一些功能,然后您添加新功能。您基本上可以通过组合和/或继承来做到这一点。

同时,您几乎总是使用接口(用于测试和生产代码)来确保低耦合、依赖倒置、依赖注入和模拟。

你如何管理这个?

我的意思是,例如:您创建了一个类,现在它必须包含一个新属性(例如,一个 Person 现在可以有一个电子邮件)。怎么办?

  • 修改类,添加新属性: 然后你必须添加新的构造函数。但是,如果您修改现有的构造函数,那么您必须重构所有涉及的 TEST,而不仅仅是生产代码。您可以尝试在添加新属性时保留所有构造函数,但最后大多变得无用、过时(仅由于 TESTS 而存在),具有“构造函数调用另一个构造函数”的复杂逻辑(或使用某种“工厂” )
  • 派生类:这更符合 OCP。但是,如果您通过小步骤创建一个真正的 TDD,如果您总是从一个非常简单的类开始派生,那么您将以极其复杂且不知何故不必要的继承结束。此外,假设您必须始终只测试 PUBLIC 暴露成员。因此,同样,随着基类受到保护,必须重构测试以访问公共测试。
  • Compose: Compose 对构造函数没有问题,但并不总是一个好的解决方案。至于我们当前的示例。

在某种程度上,接口也会发生类似的事情。

因此,随着代码的增长,构造函数和接口必须不断发展。我心中有三个戒律:

  • 您应该避免重构测试。
  • 生产代码不得保留“仅用于测试的代码”(即构造函数)
  • ISP 声明使用特定接口。随着代码的增长,其中许多变得不必要,因为它们仅用于测试(即模拟)在许多情况下应受保护或私有的类。

所以,正如我所说...我在开发 TDD 时如何管理这一切?我知道这是一个很长的问题,所以,如果你能参考一些好的文章或资源

【问题讨论】:

    标签: inheritance interface constructor tdd composition


    【解决方案1】:

    可以更改测试

    您所描述的(人现在有一个电子邮件)是规格的变化。单元测试应该是您的规范,因此在引入新数据时必须更改它们是很正常的。

    这种测试的脆弱性是对质量的一种权衡,是一种必要的弊端。

    不要过度设计

    通过尝试应用 OCP、继承和组合来添加一个字段,您只会让事情变得更复杂。正如你所指出的,它会导致生产代码怪物只是为了测试,而且你也必须修改测试。

    如果您在现有行为系列中添加新的行为,OCP 可能会很好,但这里并非如此。

    使更改更易于管理

    策略可以让您的测试更能抵抗微小的变化,但它们主要是在测试级别实现的,而不是在生产代码中。此外,如果您经常在测试中寻找重复,例如在 TDD 周期的重构步骤中,很容易发现这种机会。

    其中之一是将您的“被测系统”创建封装在Factory Method 中,并在每个测试中调用它而不是普通的构造函数。使用默认值使其大部分参数可选。这将允许您在一个地方进行更改(例如添加电子邮件字段),所有测试都将从中受益。这不会让您免于修改测试套件,但您只需在一个地方进行。

    【讨论】:

    • 感谢您的回复!我现在正在检查我忘记标记为答案的所有帖子。抱歉耽搁了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-21
    • 1970-01-01
    • 2021-02-15
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    相关资源
    最近更新 更多