验证构造函数中的方法调用
Verify method call in constructor
我有以下规格:
@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: No such property: holder for
class: Whatever
在以下行中:
1 * binder.bind(holder, view)
在 then
块中。
我知道它为什么会失败,因为 then
在 when
块之前计算。问题是,它如何在没有任何棘手的解决方法的情况下测试此 binder.bind()
构造函数调用?
您可以简单地在 given:
块中定义 holder
:
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
我们需要一个 closure to capture the arguments:
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
}
我有以下规格:
@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: No such property: holder for class: Whatever
在以下行中:
1 * binder.bind(holder, view)
在 then
块中。
我知道它为什么会失败,因为 then
在 when
块之前计算。问题是,它如何在没有任何棘手的解决方法的情况下测试此 binder.bind()
构造函数调用?
您可以简单地在 given:
块中定义 holder
:
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
我们需要一个 closure to capture the arguments:
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
}