如何将闭包返回的 "data provider" 更改为 "data provider"?

How to change the "data provider" returned from a closure into a "data provider"?

这是在 "data driven" 使用 Spock 进行测试的上下文中:

where:
key << myDriver.myMap.keySet()

...工作正常:键值已交付,参数化测试有效。

但如果我尝试这样做:

where:
key << { myDriver.myMap.keySet() } 

没用。 << 的 RHS 上的对象是 Closure。然后我尝试了很多方法试图从这个 Closure 中哄出一个 "data provider"。

我想先在那里放一个闭包,这样我就可以调试一下,但也可以提供一组更复杂的排列(不仅仅是 "key" 值,还有其他测试参数的值......见我最近的一个问题 ).

也许 keySet() 提供的 class 没有帮助:原来这是 LinkedHashMap$LinkedKeySet... 但显然是 Iterable.

我对这个 "data provider" 类别有点迷惑。在 Spock "tutorial" 中它说这必须实现 Iterable。它没有说这是否是它的全部特征。进行

{ myDriver.myMap.keySet() }.iterator()

没有帮助... iterator() 显然提供了 Iterator,而不是 Iterable。然后我得到的是这样的恐怖:

groovy.lang.MissingMethodException: No signature of method: core.MyModule.processCommand() is applicable for argument types: (core.UT_ForMyModule$__spock_feature_1_12prov0_closure8, joptsimple.OptionSet, java.util.ArrayList) values: [core.UT_ForMyModule$__spock_feature_1_12prov0_closure8@65fdd86b, ...]

... 这显然意味着它正在传递一个 Iterator 迭代一个 Collection 正好是一个 Closure.

所以,简而言之,如何从返回 Iterable 的闭包中获取 Iterable

除非你在这里延迟了执行目标,否则我相信 运行 闭包应该做的:

key << { myDriver.myMap.keySet() }()

但是注意,这会在语句中执行。