Unit testing 如何在Spock交互中匹配集合内容?
假设我在模拟的类中有以下方法:Unit testing 如何在Spock交互中匹配集合内容?,unit-testing,spock,Unit Testing,Spock,假设我在模拟的类中有以下方法: class Foo { public void doSomething(Collection<String> input) { //... } } 所以它基本上告诉我,没有一个调用看起来像我所期待的,但是有另一个调用。。。嗯,看起来就像我期待的那个 我在这里做错了什么,或者这是斯波克的一个限制,我需要检查一个闭包中的收集内容,比如 1 * mock.doSomething( { it == ['foo', 'bar'] })
class Foo {
public void doSomething(Collection<String> input) {
//...
}
}
所以它基本上告诉我,没有一个调用看起来像我所期待的,但是有另一个调用。。。嗯,看起来就像我期待的那个
我在这里做错了什么,或者这是斯波克的一个限制,我需要检查一个闭包中的收集内容,比如
1 * mock.doSomething( { it == ['foo', 'bar'] })
这都是因为
HashSet
的一个实例作为模拟调用的参数传递,而List
的一个实例在when
块中传递[]
是groovy中的ArrayList
,存在类型不匹配的问题,但是打印到控制台的Set
和List
看起来非常相似。以下测试运行良好:
@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
}
}
@Grab('org.spockframework:spock-core:0.7-groovy-2.0')
@抓取('cglib:cglib nodep:3.1')
导入spock.lang*
类测试扩展了规范{
def“测试”(){
设置:
def lol=模拟(lol)
什么时候:
def hashSet=新的hashSet(['foo','bar'])
lol.doSomething(哈希集)
然后:
1*lol.doSomething(新哈希集(['foo','bar']))
}
}
类Lol{
公共无效剂量测定(收集输入){
println输入
}
}
实际上,无论我使用哪种实际类型的集合作为doSomething方法的签名,都清楚地表明允许任何类型的集合,可能是HashSet、LinkedList、ArrayList或其他类型的集合,我都希望它能起作用。当API实际指定您可以使用任何集合时,我真的不认为这是正确的,但是如果您的合作者没有使用与您用于设置模拟的完全相同的集合类型,那么您的测试将失败。根据合同定义,它工作得很好,您创建的API的客户端可以使用集合的任何子类型
,但是当涉及到测试传递的确切参数时,会进行检查,因此我不同意您的看法。如果需要检查是否传递了集合
的实例,请尝试it instanceof Collection
。回答自己需要测试什么,实际数据还是实际数据类型?事实证明这是不一样的。在这个特定的例子中,我需要检查数据,我不关心收集的类型。所以我想我必须坚持到底。因此,这并不是一个比现在更好的解决方案,但至少讨论帮助了我,所以我接受了这个答案。
1 * mock.doSomething( { it == ['foo', 'bar'] })
@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
}
}