在Groovy单元测试下面的任务是很常见的:在Groovy /斯波克断言调用方法不与斯波克执行
assert myResult == calculateExpectedResult()
(不管有没有assert
关键字)。
Groovy的断言打印出很多关于这里发生了什么的信息以及为什么我的断言失败。但是,当比较对象非常复杂和深入时,可能会非常棘手,以获取测试失败的具体属性。
为此,我发现了Javers Framework,它做了一个很好的比较对象并生成一个确切的差异的工作。我创建了一个特点,以做到这一点:
trait DiffTrait {
Javers javers = JaversBuilder.javers().build()
String diff(result, expected) {
Diff diff = javers.compare(result, expected);
def valueChanges = diff.getChangesByType(ValueChange)
String message = ""
valueChanges.each { message += "\n$it.propertyName = $it.left instead of expected: $it.right" }
return message
}
}
现在我可以用它在我的单元测试是这样的:
def expected = calculateExpectedResult()
assert myResult == expected, diff(myResult, expected)
这样,我得到的差异的精细打印的清单。
但是这是一种冗长,因为我必须指定值两次。
所以我已经改变了特点如下:
trait DiffTrait {
Javers javers = JaversBuilder.javers().build()
def result
def expected
String diff(result, expected) {
Diff diff = javers.compare(result, expected);
def valueChanges = diff.getChangesByType(ValueChange)
String message = ""
valueChanges.each { message += "\n$it.propertyName = $it.left instead of expected: $it.right" }
return message
}
String diff() {
diff(result, expected)
}
def result(result) {
this.result = result
return result
}
def expected(expected) {
this.expected = expected
return expected
}
}
当时的想法是这样使用它:
def result = callTheSystemToProduceTheRealResult()
def expected = calculateExpectedResult()
assert result(myResult) == expected(expected), diff()
但出乎意料的是,这并不工作!这两个属性是空的,diff方法失败并带有NotNull-Exception。如果我调试此代码,则永远不会调用方法expected
/result
!
如果我重写按预期工作这样
def result = result(callTheSystemToProduceTheRealResult())
def expected = expected(calculateExpectedResult())
assert myResult == expected, diff()
一切的代码。方法被正确调用并且属性被设置。
我的问题是:为什么我不能在assert语句中调用这些方法?这两个代码片段的Groovy/Spock观点有什么不同?
这是一个gist包含所有代码作为运行示例。