我有以下规范:
@Grab('org.spockframework:spock-core:1.0-groovy-2.4')
@Grab('cglib:cglib:3.1')
@Grab('org.ow2.asm:asm-all:5.0.3')
import spock.lang.*
class Whatever extends Specification {
def "bind view to object in constructor" () {
given:
def view = Mock(View)
def binder = Mock(Binder)
when:
def holder = new Holder(binder, view)
then:
1 * binder.bind(holder, view)
}
}
class Binder {
def bind(Holder holder, View view) {}
}
class View {}
class Holder {
Holder(Binder binder, View view) {
binder.bind(this, view)
}
}
失败了:
groovy.lang.MissingPropertyException:没有这样的属性:holder for class:Whatever
在以下一行:
1 * binder.bind(holder, view)
then
块中的。
我知道它失败的原因,因为在then
阻止之前评估了when
。问题是,如何在没有任何棘手的解决方法的情况下测试这个binder.bind()
构造函数调用?
答案 0 :(得分:2)
您只需在holder
块中定义given:
:
class Whatever extends Specification {
def "bind view to object in constructor" () {
given:
def view = Mock(View)
def binder = Mock(Binder)
def holder
when:
holder = new Holder(binder, view)
then:
1 * binder.bind(holder, view)
}
}
然而,失败了:
Too few invocations for:
1 * binder.bind(holder, view) (0 invocations)
Unmatched invocations (ordered by similarity):
1 * binder.bind(Holder@519b27f6, Mock for type 'View' named 'view')
因为验证互动时尚未分配holder
。因此,为了测试交互,最好这样做:
class Whatever extends Specification {
def "bind view to object in constructor" () {
given:
def view = Mock(View)
def binder = Mock(Binder)
when:
new Holder(binder, view)
then:
1 * binder.bind(!null, view) // or 1 * binder(_ as Holder, view)
}
}
如果我们仍想检查holder
,我们需要http://i.stack.imgur.com/Xypas.png:
def "bind view to object in constructor" () {
given:
def view = Mock(View)
def binder = Mock(Binder)
def holder
def argHolder
when:
holder = new Holder(binder, view)
then:
1 * binder.bind(*_) >> { arguments ->
argHolder = arguments[0]
assert view == arguments[1]
}
assert argHolder == holder
}