我在Spock交互文档中找到了有趣的一行:
http://spockframework.org/spock/docs/1.3/interaction_based_testing.html#_argument_constraints
约束的最后一行,带有关闭谓词的示例:
1 * subscriber.receive({ it.size() > 3 && it.contains('a') })
我的问题是:Groovy中是否有一种方法可以将此谓词作为变量传递?
我的测试环境代码:
class Something {
Doer doer
Something(Doer doer) {
this.doer = doer
}
boolean doSth(x) {
if (!doer.validate(x)) throw new RuntimeException()
true
}
}
class Doer {
boolean validate(int x) {
x == 2
}
}
和测试代码:
def "some test"() {
given:
def d = Mock(Doer)
def s = new Something(d)
when:
s.doSth(2)
then:
1 * d.validate({ it == 2 }) >> true
}
我想实现的目标:
def "some test"() {
given:
def d = Mock(Doer)
def s = new Something(d)
def myClosureVar = { ??? }
when:
s.doSth(2)
then:
1 * d.validate(myClosureVar) >> true
}
it
所定义的值。该值是相应的方法参数。因此,无论您在交互之外定义了什么闭合,都需要确保交互将该参数移交给闭合,即,您需要创建自己的(小而简单的)闭合来评估外部(可能更长,更复杂)的闭合使用参数it
:1 * d.validate({ myClosureVar(it) }) >> true
很抱歉重复,但是我总是希望答案中带有完整的MCVE,以便您可以轻松地复制,粘贴,编译和运行:应用程序类:
package de.scrum_master.stackoverflow.q60341734 class Doer { boolean validate(int x) { x == 2 } }
package de.scrum_master.stackoverflow.q60341734
class Something {
Doer doer
Something(Doer doer) {
this.doer = doer
}
boolean doSth(x) {
if (!doer.validate(x)) throw new RuntimeException()
true
}
}
Spock规范:
package de.scrum_master.stackoverflow.q60341734 import org.junit.Rule import org.junit.rules.TestName import spock.lang.Specification class SomethingTest extends Specification { @Rule TestName testName def "some test"() { given: def d = Mock(Doer) def s = new Something(d) when: s.doSth(2) then: 1 * d.validate({ println "$testName.methodName: closure parameter = $it"; it == 2 }) >> true } def "another test"() { given: def d = Mock(Doer) def s = new Something(d) def myClosureVar = { println "$testName.methodName: closure parameter = $it"; it == 2 } when: s.doSth(2) then: 1 * d.validate({ myClosureVar(it) }) >> true } }
控制台日志:
some test: closure parameter = 2 another test: closure parameter = 2