在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包含所有代碼作爲運行示例。