Java 斯波克:在a";其中;子句表?

Java 斯波克:在a";其中;子句表?,java,mocking,spock,Java,Mocking,Spock,我试图在“where”子句的表中使用模拟对象。基本上是这样的: def "my test"(){ given: InjectedObject1 inj1 = Mock() InjectedObject2 inj2 = Mock() SystemUnderTest system = new System(inj1, inj2) MockedObject mocked = Mock() inj1.someMethod() >> list

我试图在“where”子句的表中使用模拟对象。基本上是这样的:

def "my test"(){

    given:
    InjectedObject1 inj1 = Mock()
    InjectedObject2 inj2 = Mock()
    SystemUnderTest system = new System(inj1, inj2)
    MockedObject mocked = Mock()

    inj1.someMethod() >> list  // this will be a list of MockedObject

    when:
    system.execute()

    then:
    n * inj2.someOtherMethod()

    where:
    list             | n
    [mocked]         | 0
    [mocked, mocked] | 1
}
这不起作用,因为“where”子句是在“given”子句之前执行的,所以当它第一次被引用时,
mocked
还不存在。我如何克服这个问题
mocked
中仅使用此测试,因此我希望避免在该方法之外创建它


请注意,这是一个简化的示例,表中实际上有更多的交互和其他列对
n
-产生影响,这使得表语法非常方便。

您可以将该方法重构为如下内容:

...
inj1.someMethod() >> [mocked] * numReturned
...
then:
numCalled * inj2.someOtherMethod()

where:
numReturned | numCalled
1           | 0
2           | 1
换句话说,在where块中指定(仅)零件并在方法体中组装它们。这是一个常见的解决方案


通常,另一种解决方案是将where块中要使用的对象洗牌到
@共享的
字段中。“范围过大”问题可以通过在同一个文件中包含多个小规范来缓解。然而,这个解决方案对mock不起作用,因为mock不能
@共享

我考虑过这样做,在我的情况下它会起作用,但是如果这个列表必须更复杂(比如,混合不同的mock对象,以不同的顺序等),该怎么办?当然,作为解决方案的推广,您可以在“where”表中使用int,并在“given”子句中使用开关来生成所需的模拟,但这有点违背了nice表语法的目的……每个工具都有其局限性。请随时在以下地址提交功能请求:)感谢您在Spock@peter上的工作。