【发布时间】:2018-11-22 22:11:23
【问题描述】:
list.stream().forEach(e -> { dbCall.delete(e.Id());});
列表中的每个项目都会从数据库中删除。
假设列表中有3个项目,如何进行单元测试:
- Delete 被调用了 3 次。
- 删除被称为“按顺序/顺序”,即列表中元素的顺序?
【问题讨论】:
-
由于您使用的是明确无序的
forEach,因此测试调用是否按顺序完成是没有意义的。但无论如何,您要求的不是单元测试。您正在尝试验证实施细节。如果该语句做了正确的事情,并且正确的事情是删除指定的三个条目,这就是您应该验证的内容,谁在乎哪个方法以什么顺序被调用?测试代码是否删除了三个指定项的方法,不取决于你是使用循环,list.forEach,还是list.stream().forEach(…)。 -
@Holger
forEach不是“明确无序”;对于顺序流,它保证是有序的,对于并行流是隐式无序的。此外,删除的顺序可能很重要,例如,如果列表是按数据库强制执行的项目之间的引用关系排序的。牵强,也许,不是最好的设计,也许,但可能。 -
@daniu 你是怎么得出这个结论的? documentation of
forEach明确表示:“此操作的行为是明确的不确定性”。 As said by one of the authors 关于并行流执行的声明不允许对顺序流得出相反的结论。但是对于单元测试,顺序仍然无关紧要。重要的是,这三个项目是否被正确删除。 -
@Holger 我得出这个结论是因为在这种情况下,流来自
List,其行为与调用List#forEach相同,在迭代顺序(如果指定了迭代顺序)”(docs.oracle.com/javase/8/docs/api/java/lang/…)。 Brian 的陈述是关于Stream#forEach调用的一般情况,例如也适用于从无序Collection创建的流。你是对的,“保证”是不正确的——但 JDK 从未改变过现有的行为。 -
@Holger 至于顺序在单元测试中无关紧要,那是不正确的。 “三项正确删除”是操作需求,单元测试(严格意义上)验证技术行为。另外,一般来说,调用顺序很好地在单元测试的范围内:如果这是三个不同的服务调用而不是数据库删除,我相信你会同意顺序可能是相关的,我们不会有这个讨论.
标签: java unit-testing testing java-stream