如何在 Spock 交互中匹配集合内容?

How to match collection contents in Spock interactions?

鉴于我在我模拟的 class 中有以下方法:

class Foo {
   public void doSomething(Collection<String> input) {
     //...
   }
}

现在我在我的 Spock 测试中模拟这个 class 我想验证一个交互:

def test() {
    setup:
    def myMock = Mock(Foo)

    when:
    def hashSet = new HashSet<String>(['foo', 'bar'])
    myMock.doSomething(hashSet)

    then:
    1 * myMock.doSomething(['foo', 'bar'])

}

但是这种互动不会触发。真正奇怪的是输出告诉我:

too few invocations for:

1 * myMock.doSomething(['foo', 'bar'])   (0 invocations)

Unmatched invocations (ordered by similarity):

1 * myMock.doSomething(['foo', 'bar'])

所以它基本上告诉我,没有一个调用看起来像我期待的那个,但有另一个调用...... ermm 看起来像我期待的那个。

我是不是做错了什么,或者这是 Spock 的限制,我需要检查闭包中的集合内容,例如

1 * mock.doSomething( { it == ['foo', 'bar'] })

这都是因为 HashSet 的实例作为参数传递给模拟调用,而 List 的实例在 when 块中传递。 [] 是 groovy 中的 ArrayList - 类型不匹配 - 但打印到控制台的 SetList 看起来非常相似。以下测试运行良好:

@Grab('org.spockframework:spock-core:0.7-groovy-2.0')
@Grab('cglib:cglib-nodep:3.1')

import spock.lang.*

class Test extends Specification {

    def "test"() {
        setup:
        def lol = Mock(Lol)

        when:
        def hashSet = new HashSet<String>(['foo', 'bar'])
        lol.doSomething(hashSet)

        then:
        1 * lol.doSomething(new HashSet<String>(['foo', 'bar']))
    }
}

class Lol {
   public void doSomething(Collection<String> input) {
       println input
   }
}