【发布时间】:2012-05-19 18:42:20
【问题描述】:
请参阅标题中的问题!你会“注入”还是“新”一个比较器?如果规范中设置了元素的顺序并且可能不会改变,你会新它吗?
【问题讨论】:
-
好问题!答案揭示了关于注入从根本上用于的各种想法。
标签: java unit-testing dependency-injection tdd comparator
请参阅标题中的问题!你会“注入”还是“新”一个比较器?如果规范中设置了元素的顺序并且可能不会改变,你会新它吗?
【问题讨论】:
标签: java unit-testing dependency-injection tdd comparator
问题“我应该注入这种依赖关系吗?”真的是“引用对象应该知道这种依赖的性质吗?”。呃,只能否定。
如果您的班级是FastestPonyFinder,并且需要按速度对List<Pony> 进行排序,那么我会说它应该知道比较器。比较器需要按速度进行比较,排序最快到列表头部;没有其他比较器适合这项工作。该对象应该创建比较器,就像它创建 List 一样。
如果你的班级是BestPonyFinder,那么它可能应该注入比较器,因为构成“最佳”的定义与如何找到符合它的小马的定义是分开的。这将使您的代码更易于测试,并且将来更易于更改。
【讨论】:
TodaysPoniesFinder 的工作是列出今天所有参赛的小马,那么我会说FastestPonyFinder 不需要知道它在做什么;它只关心它产生一个小马列表。因此,应该注入。它可能应该作为某种类型的参数注入,例如“PonyFinder”,而不是具体类型。
TodaysPoniesFinder 将是完全可测试的 - 只要您将“今天”的值注入其中!这是classic move in mockist TDD;您通常会编写一些非常简单的class Clock { public Date now() { return new Date(); } } 并将其注入到任何需要知道时间的对象中。然后,您可以注入一个模拟来代替测试。
比较器的问题在于它们便宜。它们通常没有任何字段,即使有,也没有很多。
它们太便宜了,这并不重要。您可以内联构造它们,或者从静态 final 字段中获取它们,或者进行单例注入——谁在乎?
【讨论】:
另外,如果没有状态,你可以随时“重用”那么。在这种情况下,它们是线程安全的,不会进入先前使用的状态。所以它最终真的取决于你如何实现比较器:有状态还是没有状态。
【讨论】:
为了进行单元测试,最好使用新的 Comparator 实例,但如果您的比较器仅实现 compare 方法并不重要。如果你想将一些数据作为状态注入到比较器并且它可以改变使用之前和之后的测试方法,以确保你不使用以前的上下文。
【讨论】: