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

时间:2015-04-02 08:47:52

标签: unit-testing spock

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

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

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

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'])

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

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

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

1 个答案:

答案 0 :(得分:2)

这一切都是因为HashSet的实例作为参数传递给模拟调用,而List的实例在when块中传递。 []在常规中是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
   }
}