Page 1 of 1

并且能够适应随时间的变化

Posted: Wed Dec 11, 2024 8:34 am
by samiul51
现在我们可以构建多个引擎实现,从而构建具有不同引擎的汽车:


现在可以进行隔离测试,因为我们可以创建 Engine 抽象的模拟实现并将其传递给我们的 Car 类:


当处理需要其他对象(依赖项)的对象时,葡萄牙电话号码库 您应该通过构造函数参数(依赖项注入)提供它们,最好隐藏在某种抽象后面。

通过遵循这种模式,您的代码将变得更具可读性,。此外,您应该避免在构造函数中执行实际工作 - 除了字段赋值之外的任何工作都是实际工作。构造函数中的 `new` 关键字始终是不可测试代码的警告信号。

这里要注意的一点是,在某些情况下,紧密耦合(例如,构造函数中的 new 关键字、用于逻辑隔离的内部类、对象映射器)并不是一个坏习惯 - 这些类作为“独立”类是没有意义的。

Image

全局状态
共享全局状态通常会产生不稳定的测试(有时通过,有时失败),尤其是在多线程环境中。

想象一下这样一个场景:多个受测对象共享相同的全局状态 - 如果其中一个对象中的方法触发了副作用,从而改变了共享全局状态的值,则另一个对象中方法的输出将变得不可预测。避免使用不纯的静态方法,因为它们会以某种方式改变全局状态或代理到某个全局状态。

我们来看看这个非纯静态方法:


本质上,此方法读取当前系统日期和时间并根据该值返回结果。为此方法编写适当的基于状态的单元测试非常困难,因为 LocalDateTime.now() 静态调用将在执行测试期间产生不同的结果。如果不更改系统日期和时间,就不可能为此方法编写测试。

为了解决这个问题,我们将日期时间作为参数传递给 timeOfDay 方法:


timeOfDay 静态方法现在是纯的——相同的输入总是产生相同的结果。现在我们可以轻松地在测试中将孤立的 dateTime 对象作为参数传递:


迪米特法则
迪米特法则,又称最少知识原则,规定对象应该只了解与第一个对象密切相关的对象。换句话说,一个对象应该只能访问它需要的对象。例如,我们有一个接受上下文对象作为参数的方法:


此方法违反了迪米特法则,因为它需要遍历对象图来获取完成其工作所需的信息。将不必要的信息传递到类和方法中会损害可测试性。

想象一个巨大的 BillingContext 对象,其中包含对其他对象的引用:


我们可以看到,我们的测试充斥着不必要的信息。创建复杂对象图的测试难以阅读,并引入了不必要的复杂性。

让我们修复前面的示例