派生,组合,构造函数,接口和TDD

时间:2015-05-14 20:29:30

标签: inheritance interface constructor tdd composition

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

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

你如何管理这个?

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

  • 修改类,添加新属性:然后必须添加新的构造函数。但是如果你修改现有的构造函数,那么你必须重构所有涉及的TEST,而不仅仅是生产代码。您可以尝试在添加新属性时保留所有构造函数,但最终大部分变得无用,过时(仅因为TESTS而存在),并且构造函数的复杂逻辑调用另一个构造函数' (或使用某种'工厂')
  • 导出课程:这对OCP更为擅长。但是如果你用一个小步骤制作一个真正的TDD,如果你总是派生出来,从一个非常简单的类开始,你将以一个非常复杂的,不知何故的不必要的继承结束。此外,它假设您始终必须只测试PUBLIC公开的成员。因此,当基类受到保护时,必须重构测试以访问公共类。
  • 撰写:组合对构造函数没有任何问题,但并不总是一个好的解决方案。至于我们目前的例子。

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

因此,随着代码的增长,构造函数接口必须发展。我有三条戒律:

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

所以,正如我所说的......在开发TDD的过程中,我如何管理这一切?我知道这是一个长期答案的问题,所以,如果你可以参考一些好文章或资源

1 个答案:

答案 0 :(得分:0)

更改测试即可

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

这种测试的脆弱性是对质量的折衷,是必要的邪恶。

不要过度工程

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

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

使更改更易于管理

策略可以使您的测试更能抵御小的更改,但它们主要在测试级别实现,而不是在生产代码中实现。此外,如果您经常在TDD循环的重构步骤中查找测试中的重复,则很容易发现这种情况。

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